From e8f91c93de3599309d8fe11fd94318bfdc51d36c Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Thu, 12 Feb 2009 15:59:43 +0100 Subject: Merge branch 'gl2text' of ..\qt-main --- src/opengl/gl2paintengineex/qglshader.cpp | 16 ++- src/opengl/gl2paintengineex/qglshader_p.h | 1 + .../gl2paintengineex/qpaintengineex_opengl2.cpp | 6 ++ src/opengl/opengl.pro | 12 +-- src/opengl/qgl.cpp | 25 ++++- src/opengl/qglextensions.cpp | 21 +++- src/opengl/qglextensions_p.h | 111 ++++++++++++++++++++- src/opengl/qglframebufferobject.cpp | 8 +- src/opengl/qglpixelbuffer.cpp | 10 +- src/opengl/qglpixmapfilter.cpp | 20 ++-- src/opengl/qwindowsurface_gl.cpp | 8 +- 11 files changed, 207 insertions(+), 31 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglshader.cpp b/src/opengl/gl2paintengineex/qglshader.cpp index 634be84..4ac6e61 100644 --- a/src/opengl/gl2paintengineex/qglshader.cpp +++ b/src/opengl/gl2paintengineex/qglshader.cpp @@ -49,7 +49,11 @@ return false; \ ctx->makeCurrent(); \ - +#if !defined(QT_OPENGL_ES_2) +static const char *qglslDefines = "#define lowp\n#define mediump\n#define highp\n"; +#else +static const char *qglslDefines = ""; +#endif class QGLShaderPrivate @@ -131,9 +135,13 @@ bool QGLShader::compile() return false; const QByteArray src_ba = d->source.toAscii(); - const char* src = src_ba.constData(); + const char* src[2]; + src[0] = qglslDefines; + src[1] = src_ba.constData(); + - glShaderSource(d->shaderId, 1, &src, 0); + QGLContext *ctx = d->ctx; + glShaderSource(d->shaderId, 2, src, 0); glCompileShader(d->shaderId); @@ -160,6 +168,7 @@ QString QGLShader::log() GLint logSize; GLint logLength; + QGLContext *ctx = d->ctx; glGetShaderiv(d->shaderId, GL_INFO_LOG_LENGTH, &logSize); if (!logSize) @@ -377,6 +386,7 @@ void QGLShaderProgram::use() if (!d->valid) return; + QGLContext *ctx = d->ctx; glUseProgram(d->programId); } diff --git a/src/opengl/gl2paintengineex/qglshader_p.h b/src/opengl/gl2paintengineex/qglshader_p.h index 1625b84..4cbf3f6 100644 --- a/src/opengl/gl2paintengineex/qglshader_p.h +++ b/src/opengl/gl2paintengineex/qglshader_p.h @@ -81,6 +81,7 @@ SAMPLER_2D_SHADOW. #include +#include typedef struct { GLfloat a; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index a74f044..2948e62 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -845,6 +845,7 @@ void QGL2PaintEngineEx::transformChanged() void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src) { Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; glActiveTexture(QT_BRUSH_TEXTURE_UNIT); d->ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true); @@ -862,6 +863,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const Qt::ImageConversionFlags) { Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; glActiveTexture(QT_BRUSH_TEXTURE_UNIT); d->ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); @@ -926,6 +928,7 @@ void QGL2PaintEngineEx::drawCachedGlyphs(const QPointF &p, const QTextItemInt &t const QImage &image = cache->image(); int margin = cache->glyphMargin(); + QGLContext *ctx = d->ctx; glActiveTexture(QT_BRUSH_TEXTURE_UNIT); d->ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); @@ -1000,6 +1003,9 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->width = widget->width(); d->height = widget->height(); + qt_resolve_version_1_3_functions(d->ctx); + qt_resolve_glsl_extensions(d->ctx); + if (!d->shaderManager) d->shaderManager = new QGLPEXShaderManager(d->ctx); diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 48d7caf..af16312 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -34,12 +34,12 @@ SOURCES += qgl.cpp \ qglextensions.cpp \ qglpixmapfilter.cpp -!contains(QT_CONFIG, opengles2) { - HEADERS += qpaintengine_opengl_p.h - SOURCES += qpaintengine_opengl.cpp -} +#!contains(QT_CONFIG, opengles2) { +# HEADERS += qpaintengine_opengl_p.h +# SOURCES += qpaintengine_opengl.cpp +#} -contains(QT_CONFIG, opengles2) { +#contains(QT_CONFIG, opengles2) { SOURCES += gl2paintengineex/qglgradientcache.cpp \ gl2paintengineex/qglpexshadermanager.cpp \ gl2paintengineex/qglshader.cpp \ @@ -51,7 +51,7 @@ contains(QT_CONFIG, opengles2) { gl2paintengineex/qglshader_p.h \ gl2paintengineex/qgl2pexvertexarray_p.h \ gl2paintengineex/qpaintengineex_opengl2_p.h -} +#} x11 { diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 4c152e2..386e9b8 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -65,7 +65,7 @@ #include "qimage.h" #include "qgl_p.h" -#if defined(QT_OPENGL_ES_2) +#if 1 || defined(QT_OPENGL_ES_2) #include "gl2paintengineex/qpaintengineex_opengl2_p.h" #else #include @@ -2041,7 +2041,24 @@ void QGLContext::deleteTexture(QMacCompatGLuint id) // qpaintengine_opengl.cpp #if !defined(QT_OPENGL_ES_2) -extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array); +//extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array); +void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) +{ + qreal left = r.left(); + qreal right = r.right(); + qreal top = r.top(); + qreal bottom = r.bottom(); + + array[0] = f2vt(left); + array[1] = f2vt(top); + array[2] = f2vt(right); + array[3] = f2vt(top); + array[4] = f2vt(right); + array[5] = f2vt(bottom); + array[6] = f2vt(left); + array[7] = f2vt(bottom); +} + #else void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) {}; #endif @@ -4039,14 +4056,14 @@ void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QM } #endif -#if defined(QT_OPENGL_ES_2) +#if 1 || defined(QT_OPENGL_ES_2) Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_engine) #else Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine) #endif #ifdef Q_WS_QWS -Q_OPENGL_EXPORT QOpenGLPaintEngine* qt_qgl_paint_engine() +Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine() { #if !defined(QT_OPENGL_ES_2) return qt_gl_engine(); diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp index 8357cf9..b054fe8 100644 --- a/src/opengl/qglextensions.cpp +++ b/src/opengl/qglextensions.cpp @@ -176,10 +176,29 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glUniform1fv = (_glUniform1fv) ctx->getProcAddress(QLatin1String("glUniform1fv")); glUniform1i = (_glUniform1i) ctx->getProcAddress(QLatin1String("glUniform1i")); + glGetActiveAttrib = (_glGetActiveAttrib) ctx->getProcAddress(QLatin1String("glGetActiveAttrib")); + glGetAttribLocation = (_glGetAttribLocation) ctx->getProcAddress(QLatin1String("glGetAttribLocation")); + glGetActiveUniform = (_glGetActiveUniform) ctx->getProcAddress(QLatin1String("glGetActiveUniform")); + glGetProgramInfoLog = (_glGetProgramInfoLog) ctx->getProcAddress(QLatin1String("glGetProgramInfoLog")); + glUniform1f = (_glUniform1f) ctx->getProcAddress(QLatin1String("glUniform1f")); + glUniform2f = (_glUniform2f) ctx->getProcAddress(QLatin1String("glUniform2f")); + glUniform4f = (_glUniform4f) ctx->getProcAddress(QLatin1String("glUniform4f")); + glUniformMatrix2fv = (_glUniformMatrix2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2fv")); + glUniformMatrix3fv = (_glUniformMatrix3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3fv")); + glUniformMatrix4fv = (_glUniformMatrix4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4fv")); + glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArray")); + glDisableVertexAttribArray = (_glDisableVertexAttribArray) ctx->getProcAddress(QLatin1String("glDisableVertexAttribArray")); + glVertexAttribPointer = (_glVertexAttribPointer) ctx->getProcAddress(QLatin1String("glVertexAttribPointer")); + glStencilOpSeparate = (_glStencilOpSeparate) ctx->getProcAddress(QLatin1String("glStencilOpSeparate")); + return glCreateShader && glShaderSource && glCompileShader && glDeleteProgram && glCreateProgram && glAttachShader && glDetachShader && glLinkProgram && glUseProgram && glDeleteProgram && glGetShaderInfoLog && glGetShaderiv && glGetProgramiv && glGetUniformLocation && - glUniform1i && glUniform1fv && glUniform2fv && glUniform3fv && glUniform4fv; + glUniform1i && glUniform1fv && glUniform2fv && glUniform3fv && glUniform4fv && + glGetActiveAttrib && glGetAttribLocation && glGetActiveUniform && glGetProgramInfoLog && + glUniform1f && glUniform2f && glUniform4f && + glUniformMatrix2fv && glUniformMatrix3fv && glUniformMatrix4fv && + glEnableVertexAttribArray && glDisableVertexAttribArray && glVertexAttribPointer && glStencilOpSeparate; } QT_END_NAMESPACE diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index a0517f5..fdf0bba 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -74,6 +74,10 @@ typedef ptrdiff_t GLsizeiptrARB; #endif +#ifndef GL_VERSION_2_0 +typedef char GLchar; +#endif + // ARB_pixel_buffer_object typedef void (APIENTRY *_glBindBufferARB) (GLenum, GLuint); typedef void (APIENTRY *_glDeleteBuffersARB) (GLsizei, const GLuint *); @@ -107,10 +111,10 @@ typedef void (APIENTRY *_glGetShaderiv) (GLuint, GLenum, GLint *); typedef void (APIENTRY *_glGetProgramiv) (GLuint, GLenum, GLint *); typedef GLuint (APIENTRY *_glGetUniformLocation) (GLuint, const char*); -typedef void (APIENTRY *_glUniform4fv) (GLint, GLsizei, GLfloat *); -typedef void (APIENTRY *_glUniform3fv) (GLint, GLsizei, GLfloat *); -typedef void (APIENTRY *_glUniform2fv) (GLint, GLsizei, GLfloat *); -typedef void (APIENTRY *_glUniform1fv) (GLint, GLsizei, GLfloat *); +typedef void (APIENTRY *_glUniform4fv) (GLint, GLsizei, const GLfloat *); +typedef void (APIENTRY *_glUniform3fv) (GLint, GLsizei, const GLfloat *); +typedef void (APIENTRY *_glUniform2fv) (GLint, GLsizei, const GLfloat *); +typedef void (APIENTRY *_glUniform1fv) (GLint, GLsizei, const GLfloat *); typedef void (APIENTRY *_glUniform1i) (GLint, GLint); typedef void (APIENTRY *_glActiveStencilFaceEXT) (GLenum ); @@ -118,6 +122,22 @@ typedef void (APIENTRY *_glActiveStencilFaceEXT) (GLenum ); typedef void (APIENTRY *_glMultiTexCoord4f) (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); typedef void (APIENTRY *_glActiveTexture) (GLenum); +typedef void (APIENTRY *_glGetActiveAttrib) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef GLint (APIENTRY *_glGetAttribLocation) (GLuint program, const GLchar* name); +typedef void (APIENTRY *_glGetActiveUniform) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +typedef void (APIENTRY *_glGetProgramInfoLog) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +typedef void (APIENTRY *_glUniform1f) (GLint location, GLfloat v0); +typedef void (APIENTRY *_glUniform2f) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRY *_glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRY *_glUniformMatrix2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (APIENTRY *_glUniformMatrix3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (APIENTRY *_glUniformMatrix4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +typedef void (APIENTRY *_glEnableVertexAttribArray) (GLuint); +typedef void (APIENTRY *_glDisableVertexAttribArray) (GLuint); +typedef void (APIENTRY *_glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); +typedef void (APIENTRY *_glStencilOpSeparate) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + + // EXT_GL_framebuffer_object typedef GLboolean (APIENTRY *_glIsRenderbufferEXT) (GLuint renderbuffer); typedef void (APIENTRY *_glBindRenderbufferEXT) (GLenum target, GLuint renderbuffer); @@ -207,6 +227,21 @@ struct QGLExtensionFuncs qt_glBufferDataARB = 0; qt_glMapBufferARB = 0; qt_glUnmapBufferARB = 0; + + qt_glGetActiveAttrib = 0; + qt_glGetAttribLocation = 0; + qt_glGetActiveUniform = 0; + qt_glGetProgramInfoLog = 0; + qt_glUniform1f = 0; + qt_glUniform2f = 0; + qt_glUniform4f = 0; + qt_glUniformMatrix2fv = 0; + qt_glUniformMatrix3fv = 0; + qt_glUniformMatrix4fv = 0; + qt_glEnableVertexAttribArray = 0; + qt_glDisableVertexAttribArray = 0; + qt_glVertexAttribPointer = 0; + qt_glStencilOpSeparate = 0; } _glProgramStringARB qt_glProgramStringARB; @@ -270,6 +305,21 @@ struct QGLExtensionFuncs _glBufferDataARB qt_glBufferDataARB; _glMapBufferARB qt_glMapBufferARB; _glUnmapBufferARB qt_glUnmapBufferARB; + + _glGetActiveAttrib qt_glGetActiveAttrib; + _glGetAttribLocation qt_glGetAttribLocation; + _glGetActiveUniform qt_glGetActiveUniform; + _glGetProgramInfoLog qt_glGetProgramInfoLog; + _glUniform1f qt_glUniform1f; + _glUniform2f qt_glUniform2f; + _glUniform4f qt_glUniform4f; + _glUniformMatrix2fv qt_glUniformMatrix2fv; + _glUniformMatrix3fv qt_glUniformMatrix3fv; + _glUniformMatrix4fv qt_glUniformMatrix4fv; + _glEnableVertexAttribArray qt_glEnableVertexAttribArray; + _glDisableVertexAttribArray qt_glDisableVertexAttribArray; + _glVertexAttribPointer qt_glVertexAttribPointer; + _glStencilOpSeparate qt_glStencilOpSeparate; }; @@ -416,6 +466,40 @@ struct QGLExtensionFuncs #define GL_UNPACK_IMAGE_HEIGHT 0x806E #endif +#ifndef GL_VERSION_1_4 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#endif + +#ifndef GL_VERSION_2_0 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#endif + #define glProgramStringARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glProgramStringARB #define glBindProgramARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindProgramARB #define glDeleteProgramsARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteProgramsARB @@ -502,6 +586,25 @@ struct QGLExtensionFuncs #define glUniform1fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1fv #define glUniform1i QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1i +#define glGetActiveAttrib QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetActiveAttrib +#define glGetAttribLocation QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetAttribLocation +#define glGetActiveUniform QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetActiveUniform +#define glGetProgramInfoLog QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetProgramInfoLog +#define glUniform1f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1f +#define glUniform2f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform2f +#define glUniform4f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform4f +#define glUniformMatrix2fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix2fv +#define glUniformMatrix3fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix3fv +#define glUniformMatrix4fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix4fv +#define glEnableVertexAttribArray QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glEnableVertexAttribArray +#define glDisableVertexAttribArray QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDisableVertexAttribArray +#define glVertexAttribPointer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glVertexAttribPointer +#define glStencilOpSeparate QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glStencilOpSeparate + +#if !defined(QT_OPENGL_ES_2) +#define glClearDepthf(x) glClearDepth(GLdouble(x)) +#endif + extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx); bool qt_resolve_buffer_extensions(QGLContext *ctx); diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 8524dfa..9134fc6 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -43,7 +43,11 @@ #include #include +#if 1 || defined(QT_OPENGL_ES_2) +#include +#else #include +#endif #include #include #include @@ -573,7 +577,9 @@ QImage QGLFramebufferObject::toImage() const return image; } -#if !defined(QT_OPENGL_ES_2) +#if 1 || defined(QT_OPENGL_ES_2) +Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_paintengine) +#else Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_paintengine) #endif diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 5f74f26..6a207c8 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -81,13 +81,15 @@ #include #include -#if !defined(QT_OPENGL_ES_2) +#if 1 || defined(QT_OPENGL_ES_2) +#include +#else #include #endif QT_BEGIN_NAMESPACE -#if !defined(QT_OPENGL_ES_2) +#if 0 && !defined(QT_OPENGL_ES_2) extern void qgl_cleanup_glyph_cache(QGLContext *); #else void qgl_cleanup_glyph_cache(QGLContext *) {} @@ -363,7 +365,9 @@ bool QGLPixelBuffer::isValid() const return !d->invalid; } -#if !defined(QT_OPENGL_ES_2) +#if 1 || defined(QT_OPENGL_ES_2) +Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_paintengine) +#else Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_paintengine) #endif diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index ff23948..8a64515 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -138,13 +138,6 @@ void QGLSLProgram::disable() glUseProgram(0); } -typedef GLuint (APIENTRY *_glGetUniformLocation) (GLuint, const char*); -typedef void (APIENTRY *_glUniform4fv) (GLint, GLsizei, GLfloat *); -typedef void (APIENTRY *_glUniform3fv) (GLint, GLsizei, GLfloat *); -typedef void (APIENTRY *_glUniform2fv) (GLint, GLsizei, GLfloat *); -typedef void (APIENTRY *_glUniform1fv) (GLint, GLsizei, GLfloat *); -typedef void (APIENTRY *_glUniform1i) (GLint, GLint); - int QGLSLProgram::getUniformLocation(const QString &name) { return glGetUniformLocation(m_program, name.toAscii().constData()); @@ -244,7 +237,18 @@ QPixmapFilter *QGLContextPrivate::createPixmapFilter(int type) const #if !defined(QT_OPENGL_ES_2) extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array); -extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array); +//extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array); +void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array) +{ + array[0] = f2vt(x1); + array[1] = f2vt(y1); + array[2] = f2vt(x2); + array[3] = f2vt(y1); + array[4] = f2vt(x2); + array[5] = f2vt(y2); + array[6] = f2vt(x1); + array[7] = f2vt(y2); +} #endif static void qgl_drawTexture(const QRectF &rect, int tx_width, int tx_height, const QRectF & src) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 3dd3064..bb4ffc5 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -69,7 +69,11 @@ #include #include +#if 1 || defined(QT_OPENGL_ES_2) +#include +#else #include +#endif #ifndef GLX_ARB_multisample #define GLX_SAMPLE_BUFFERS_ARB 100000 @@ -283,7 +287,9 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size(); } -#if !defined(QT_OPENGL_ES_2) +#if 1 || defined(QT_OPENGL_ES_2) +Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_window_surface_paintengine) +#else Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_paintengine) #endif -- cgit v0.12 From afdd536c50ba14ece1db63f5efab0328730f2e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 17 Feb 2009 14:10:06 +0100 Subject: Fixes: Move QGLDrawable into qgl_p.h so that we can use it in the GL 2 paint engine. RevBy: Tom Details: Now we can use the GL 2 paint engine on non-widget paint devices like pixel buffers, framebuffer objects, and GL window surfaces. Using -graphicssystem opengl works now. --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 19 +-- src/opengl/qgl.cpp | 150 ++++++++++++++++++ src/opengl/qgl_p.h | 33 ++++ src/opengl/qpaintengine_opengl.cpp | 176 --------------------- 4 files changed, 193 insertions(+), 185 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 2948e62..1cc2233 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -133,10 +133,9 @@ public: inline QColor premultiplyColor(QColor c, GLfloat opacity); QGL2PaintEngineEx* q; - - //### Move into QGLDrawable + QGLDrawable drawable; + QGLContext *ctx; int width, height; - QGLContext* ctx; // Dirty flags bool matrixDirty; // Implies matrix uniforms are also dirty @@ -997,11 +996,12 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) // qDebug("QGL2PaintEngineEx::begin()"); - QGLWidget* widget = static_cast(pdev); - d->ctx = const_cast(widget->context()); - d->ctx->makeCurrent(); - d->width = widget->width(); - d->height = widget->height(); + d->drawable.setDevice(pdev); + d->drawable.makeCurrent(); + d->ctx = d->drawable.context(); + QSize sz = d->drawable.size(); + d->width = sz.width(); + d->height = sz.height(); qt_resolve_version_1_3_functions(d->ctx); qt_resolve_glsl_extensions(d->ctx); @@ -1033,7 +1033,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) bool QGL2PaintEngineEx::end() { Q_D(QGL2PaintEngineEx); - d->ctx->swapBuffers(); + d->drawable.swapBuffers(); + d->drawable.doneCurrent(); return false; } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 386e9b8..7c42039 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -71,9 +71,14 @@ #include #endif +#include +#include + #include #include #include +#include +#include #include "qcolormap.h" #include "qcache.h" #include "qfile.h" @@ -4219,4 +4224,149 @@ Q_OPENGL_EXPORT const QString qt_gl_library_name() } #endif +void QGLDrawable::setDevice(QPaintDevice *pdev) +{ + wasBound = false; + widget = 0; + buffer = 0; + fbo = 0; +#ifdef Q_WS_QWS + wsurf = 0; +#endif + if (pdev->devType() == QInternal::Widget) + widget = static_cast(pdev); + else if (pdev->devType() == QInternal::Pbuffer) + buffer = static_cast(pdev); + else if (pdev->devType() == QInternal::FramebufferObject) + fbo = static_cast(pdev); + else if (pdev->devType() == QInternal::UnknownDevice) +#ifdef Q_WS_QWS + wsurf = static_cast(pdev)->windowSurface(); +#else + wsurf = static_cast(pdev); +#endif +} + +void QGLDrawable::swapBuffers() +{ + if (widget) { + if (widget->autoBufferSwap()) + widget->swapBuffers(); + } else { + glFlush(); + } +} + +void QGLDrawable::makeCurrent() +{ + if (widget) + widget->makeCurrent(); + else if (buffer) + buffer->makeCurrent(); + else if (wsurf) + wsurf->context()->makeCurrent(); + else if (fbo) { + wasBound = fbo->isBound(); + if (!wasBound) + fbo->bind(); + } +} + +void QGLDrawable::doneCurrent() +{ + if (fbo && !wasBound) + fbo->release(); +} + +QSize QGLDrawable::size() const +{ + if (widget) { + return QSize(widget->d_func()->glcx->device()->width(), + widget->d_func()->glcx->device()->height()); + } else if (buffer) { + return buffer->size(); + } else if (fbo) { + return fbo->size(); + } else if (wsurf) { +#ifdef Q_WS_QWS + return wsurf->window()->frameSize(); +#else + return QSize(wsurf->width(), wsurf->height()); +#endif + } + return QSize(); +} + +QGLFormat QGLDrawable::format() const +{ + if (widget) + return widget->format(); + else if (buffer) + return buffer->format(); + else if (wsurf) + return wsurf->context()->format(); + else if (fbo && QGLContext::currentContext()) { + QGLFormat fmt = QGLContext::currentContext()->format(); + fmt.setStencil(fbo->attachment() == QGLFramebufferObject::CombinedDepthStencil); + fmt.setDepth(fbo->attachment() != QGLFramebufferObject::NoAttachment); + return fmt; + } + + return QGLFormat(); +} + +GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format) +{ + if (widget) + return widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true); + else if (buffer) + return buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, true); + else if (fbo && QGLContext::currentContext()) + return const_cast(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, true); + else if (wsurf) + return wsurf->context()->d_func()->bindTexture(image, target, format, true); + return 0; +} + +GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format) +{ + if (widget) + return widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true); + else if (buffer) + return buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, true); + else if (fbo && QGLContext::currentContext()) + return const_cast(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, true); + else if (wsurf) + return wsurf->context()->d_func()->bindTexture(pixmap, target, format, true); + return 0; +} + +QColor QGLDrawable::backgroundColor() const +{ + if (widget) + return widget->palette().brush(widget->backgroundRole()).color(); + return QApplication::palette().brush(QPalette::Background).color(); +} + +QGLContext *QGLDrawable::context() const +{ + if (widget) + return widget->d_func()->glcx; + else if (buffer) + return buffer->d_func()->qctx; + else if (fbo) + return const_cast(QGLContext::currentContext()); + else if (wsurf) + return wsurf->context(); + return 0; +} + +bool QGLDrawable::autoFillBackground() const +{ + if (widget) + return widget->autoFillBackground(); + else + return false; +} + QT_END_NAMESPACE diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index b15eebc..2eccc23 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -282,6 +282,39 @@ Q_SIGNALS: void aboutToDestroyContext(const QGLContext *context); }; +class QGLPixelBuffer; +class QGLFramebufferObject; +class QWSGLWindowSurface; +class QGLWindowSurface; +class QGLDrawable { +public: + QGLDrawable() : widget(0), buffer(0), fbo(0) + , wsurf(0) + {} + void setDevice(QPaintDevice *pdev); + void swapBuffers(); + void makeCurrent(); + void doneCurrent(); + QSize size() const; + QGLFormat format() const; + GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA); + GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA); + QColor backgroundColor() const; + QGLContext *context() const; + bool autoFillBackground() const; + +private: + bool wasBound; + QGLWidget *widget; + QGLPixelBuffer *buffer; + QGLFramebufferObject *fbo; +#ifdef Q_WS_QWS + QWSGLWindowSurface *wsurf; +#else + QGLWindowSurface *wsurf; +#endif +}; + // GL extension definitions class QGLExtensions { public: diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 976a021..998492c 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -57,13 +57,11 @@ #include "qpen.h" #include "qvarlengtharray.h" #include -#include #include #include #include #include "private/qtessellator_p.h" -#include "private/qwindowsurface_gl_p.h" #include "util/fragmentprograms_p.h" @@ -190,180 +188,6 @@ const QGLTrapezoid QGLTrapezoid::translated(const QPointF &delta) const return trap; } -class QGLDrawable { -public: - QGLDrawable() : widget(0), buffer(0), fbo(0) - , wsurf(0) - {} - inline void setDevice(QPaintDevice *pdev); - inline void swapBuffers(); - inline void makeCurrent(); - inline void doneCurrent(); - inline QSize size() const; - inline QGLFormat format() const; - inline GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA); - inline GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA); - inline QColor backgroundColor() const; - inline QGLContext *context() const; - inline bool autoFillBackground() const; - -private: - bool wasBound; - QGLWidget *widget; - QGLPixelBuffer *buffer; - QGLFramebufferObject *fbo; -#ifdef Q_WS_QWS - QWSGLWindowSurface *wsurf; -#else - QGLWindowSurface *wsurf; -#endif -}; - -void QGLDrawable::setDevice(QPaintDevice *pdev) -{ - wasBound = false; - widget = 0; - buffer = 0; - fbo = 0; -#ifdef Q_WS_QWS - wsurf = 0; -#endif - if (pdev->devType() == QInternal::Widget) - widget = static_cast(pdev); - else if (pdev->devType() == QInternal::Pbuffer) - buffer = static_cast(pdev); - else if (pdev->devType() == QInternal::FramebufferObject) - fbo = static_cast(pdev); - else if (pdev->devType() == QInternal::UnknownDevice) -#ifdef Q_WS_QWS - wsurf = static_cast(pdev)->windowSurface(); -#else - wsurf = static_cast(pdev); -#endif -} - -inline void QGLDrawable::swapBuffers() -{ - if (widget) { - if (widget->autoBufferSwap()) - widget->swapBuffers(); - } else { - glFlush(); - } -} - -inline void QGLDrawable::makeCurrent() -{ - if (widget) - widget->makeCurrent(); - else if (buffer) - buffer->makeCurrent(); - else if (wsurf) - wsurf->context()->makeCurrent(); - else if (fbo) { - wasBound = fbo->isBound(); - if (!wasBound) - fbo->bind(); - } -} - -inline void QGLDrawable::doneCurrent() -{ - if (fbo && !wasBound) - fbo->release(); -} - -inline QSize QGLDrawable::size() const -{ - if (widget) { - return QSize(widget->d_func()->glcx->device()->width(), - widget->d_func()->glcx->device()->height()); - } else if (buffer) { - return buffer->size(); - } else if (fbo) { - return fbo->size(); - } else if (wsurf) { -#ifdef Q_WS_QWS - return wsurf->window()->frameSize(); -#else - return QSize(wsurf->width(), wsurf->height()); -#endif - } - return QSize(); -} - -inline QGLFormat QGLDrawable::format() const -{ - if (widget) - return widget->format(); - else if (buffer) - return buffer->format(); - else if (wsurf) - return wsurf->context()->format(); - else if (fbo && QGLContext::currentContext()) { - QGLFormat fmt = QGLContext::currentContext()->format(); - fmt.setStencil(fbo->attachment() == QGLFramebufferObject::CombinedDepthStencil); - fmt.setDepth(fbo->attachment() != QGLFramebufferObject::NoAttachment); - return fmt; - } - - return QGLFormat(); -} - -inline GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format) -{ - if (widget) - return widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true); - else if (buffer) - return buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, true); - else if (fbo && QGLContext::currentContext()) - return const_cast(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, true); - else if (wsurf) - return wsurf->context()->d_func()->bindTexture(image, target, format, true); - return 0; -} - -inline GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format) -{ - if (widget) - return widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true); - else if (buffer) - return buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, true); - else if (fbo && QGLContext::currentContext()) - return const_cast(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, true); - else if (wsurf) - return wsurf->context()->d_func()->bindTexture(pixmap, target, format, true); - return 0; -} - -inline QColor QGLDrawable::backgroundColor() const -{ - if (widget) - return widget->palette().brush(widget->backgroundRole()).color(); - return QApplication::palette().brush(QPalette::Background).color(); -} - -inline QGLContext *QGLDrawable::context() const -{ - if (widget) - return widget->d_func()->glcx; - else if (buffer) - return buffer->d_func()->qctx; - else if (fbo) - return const_cast(QGLContext::currentContext()); - else if (wsurf) - return wsurf->context(); - return 0; -} - -inline bool QGLDrawable::autoFillBackground() const -{ - if (widget) - return widget->autoFillBackground(); - else - return false; -} - class QOpenGLImmediateModeTessellator; class QGLMaskGenerator; -- cgit v0.12 From 842d514edd0ef6fa8d6e863dfe6ba696b95ba790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 17 Feb 2009 15:43:05 +0100 Subject: Get rid of warning introduced in the last commit. --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 1cc2233..e211f10 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -134,8 +134,8 @@ public: QGL2PaintEngineEx* q; QGLDrawable drawable; - QGLContext *ctx; int width, height; + QGLContext *ctx; // Dirty flags bool matrixDirty; // Implies matrix uniforms are also dirty -- cgit v0.12 From a49ec03834b14063b4130c410d59df6e8c4db8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 17 Feb 2009 16:11:41 +0100 Subject: Fixes: Improve text rendering in GL 2 paint engine. Details: Avoid adding 0.5 to dx() / dy() which caused images / glyphs to get slight antialiasing and edge artifacts. --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index e211f10..0e41602 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -399,8 +399,8 @@ void QGL2PaintEngineExPrivate::updateMatrix() // Use the (3x3) transform for the Model~View matrix: const QTransform& transform = q->state()->matrix; GLfloat MV[4][4] = { - {transform.m11(), transform.m21(), 0.0, transform.dx() + 0.5}, - {transform.m12(), transform.m22(), 0.0, transform.dy() + 0.5}, + {transform.m11(), transform.m21(), 0.0, transform.dx()}, + {transform.m12(), transform.m22(), 0.0, transform.dy()}, {0.0, 0.0, 1.0, 0.0}, {transform.m13(), transform.m23(), 0.0, transform.m33()} }; -- cgit v0.12 From 6513e4b9513dfc591c53744517f05aa3c522ace3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 18 Feb 2009 09:42:04 +0100 Subject: Fixes: GL 2 paint engine text rendering optimization. RevBy: Tom Details: Buffer vertex and texture coordinates so that we get away with just a single glDrawArrays call per text item. Also move drawCachedGlyphs() into the private class. --- src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp | 6 ++ src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h | 1 + .../gl2paintengineex/qpaintengineex_opengl2.cpp | 101 +++++++++------------ .../gl2paintengineex/qpaintengineex_opengl2_p.h | 1 - 4 files changed, 52 insertions(+), 57 deletions(-) diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp index 0352d39..f237847 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp @@ -59,6 +59,12 @@ QGLRect QGL2PEXVertexArray::boundingRect() const return QGLRect(minX, minY, maxX, maxY); } +void QGL2PEXVertexArray::addRect(const QRectF &rect) +{ + vertexArray << rect.topLeft() << rect.topRight() << rect.bottomRight() + << rect.bottomRight() << rect.bottomLeft() << rect.topLeft(); +} + void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale) { const QPointF* const points = reinterpret_cast(path.points()); diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index c205022..65f6d42 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -98,6 +98,7 @@ public: maxX(-2e10), maxY(-2e10), minX(2e10), minY(2e10), boundingRectDirty(true) {} + void addRect(const QRectF &rect); void addPath(const QVectorPath &path, GLfloat curveInverseScale); void clear(); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 0e41602..ea0d7b1 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -115,6 +115,7 @@ public: void setBrush(const QBrush* brush); void drawTexture(const QGLRect& dest, const QGLRect& src, int txtWidth, int txtHeight); + void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti); void fill(const QVectorPath &path); void drawOutline(const QVectorPath& path); @@ -152,7 +153,8 @@ public: GLfloat inverseScale; - QGL2PEXVertexArray pathVertexArray; + QGL2PEXVertexArray vertexCoordinateArray; + QGL2PEXVertexArray textureCoordinateArray; GLfloat pmvMatrix[4][4]; @@ -548,17 +550,17 @@ void QGL2PaintEngineExPrivate::drawOutline(const QVectorPath& path) if (matrixDirty) updateMatrix(); - pathVertexArray.clear(); - pathVertexArray.addPath(path, inverseScale); + vertexCoordinateArray.clear(); + vertexCoordinateArray.addPath(path, inverseScale); if (path.hasImplicitClose()) { // Close the path's outline - pathVertexArray.lineToArray(path.points()[0], path.points()[1]); - pathVertexArray.stops().last() += 1; + vertexCoordinateArray.lineToArray(path.points()[0], path.points()[1]); + vertexCoordinateArray.stops().last() += 1; } prepareForDraw(); - drawVertexArrays(pathVertexArray, GL_LINE_STRIP); + drawVertexArrays(vertexCoordinateArray, GL_LINE_STRIP); } @@ -578,26 +580,26 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) composite(rect); } else if (path.shape() == QVectorPath::EllipseHint) { - pathVertexArray.clear(); - pathVertexArray.addPath(path, inverseScale); + vertexCoordinateArray.clear(); + vertexCoordinateArray.addPath(path, inverseScale); prepareForDraw(); - drawVertexArrays(pathVertexArray, GL_TRIANGLE_FAN); + drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); } else { // The path is too complicated & needs the stencil technique - pathVertexArray.clear(); - pathVertexArray.addPath(path, inverseScale); + vertexCoordinateArray.clear(); + vertexCoordinateArray.addPath(path, inverseScale); - fillStencilWithVertexArray(pathVertexArray, path.hasWindingFill()); + fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill()); // Stencil the brush onto the dest buffer glStencilFunc(GL_NOTEQUAL, 0, 0xFFFF); // Pass if stencil buff value != 0 glEnable(GL_STENCIL_TEST); prepareForDraw(); - composite(pathVertexArray.boundingRect()); + composite(vertexCoordinateArray.boundingRect()); glDisable(GL_STENCIL_TEST); - cleanStencilBuffer(pathVertexArray.boundingRect()); + cleanStencilBuffer(vertexCoordinateArray.boundingRect()); } } @@ -876,6 +878,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem) { + Q_D(QGL2PaintEngineEx); QOpenGLPaintEngineState *s = state(); const QTextItemInt &ti = static_cast(textItem); @@ -893,17 +896,17 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem drawCached = false; if (drawCached) { - drawCachedGlyphs(p, ti); + d->drawCachedGlyphs(p, ti); return; } QPaintEngineEx::drawTextItem(p, ti); } -void QGL2PaintEngineEx::drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti) +void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti) { - Q_D(QGL2PaintEngineEx); - QOpenGLPaintEngineState *s = state(); + Q_Q(QGL2PaintEngineEx); + QOpenGLPaintEngineState *s = q->state(); QVarLengthArray positions; QVarLengthArray glyphs; @@ -927,65 +930,51 @@ void QGL2PaintEngineEx::drawCachedGlyphs(const QPointF &p, const QTextItemInt &t const QImage &image = cache->image(); int margin = cache->glyphMargin(); - QGLContext *ctx = d->ctx; glActiveTexture(QT_BRUSH_TEXTURE_UNIT); - d->ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); + ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); glEnable(GL_BLEND); - d->shaderManager->textShader()->use(); - d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); + shaderManager->textShader()->use(); + updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); - if (d->compositionModeDirty) - d->updateCompositionMode(); + if (compositionModeDirty) + updateCompositionMode(); - if (d->matrixDirty) - d->updateMatrix(); + if (matrixDirty) + updateMatrix(); - if (d->textShaderMatrixUniformDirty) { - d->shaderManager->textShader()->uniforms()[QLatin1String("pmvMatrix")] = d->pmvMatrix; - d->textShaderMatrixUniformDirty = false; + if (textShaderMatrixUniformDirty) { + shaderManager->textShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; + textShaderMatrixUniformDirty = false; } - d->shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; - QColor col = d->premultiplyColor(state()->pen.color(), (GLfloat)state()->opacity); - d->shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col; + shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; + QColor col = premultiplyColor(s->pen.color(), (GLfloat)s->opacity); + shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col; GLfloat dx = 1.0 / image.width(); GLfloat dy = 1.0 / image.height(); - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); + vertexCoordinateArray.clear(); + textureCoordinateArray.clear(); + for (int i=0; icoords.value(glyphs[i]); int x = positions[i].x.toInt() + c.baseLineX - margin; int y = positions[i].y.toInt() - c.baseLineY - margin; - QGLRect dest = QRectF(x, y, c.w, c.h); - QGLRect src = QRectF(c.x, c.y, c.w, c.h); - - GLfloat vertexCoords[] = { - dest.left, dest.top, - dest.left, dest.bottom, - dest.right, dest.bottom, - dest.right, dest.top - }; - - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoords); - - QGLRect srcTextureRect(src.left*dx, 1.0 - src.top*dy, src.right*dx, 1.0 - src.bottom*dy); + vertexCoordinateArray.addRect(QRectF(x, y, c.w, c.h)); + textureCoordinateArray.addRect(QRectF(c.x*dx, 1 - c.y*dy, c.w * dx, -c.h * dy)); + } - GLfloat textureCoords[] = { - srcTextureRect.left, srcTextureRect.top, - srcTextureRect.left, srcTextureRect.bottom, - srcTextureRect.right, srcTextureRect.bottom, - srcTextureRect.right, srcTextureRect.top - }; + glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); + glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); + glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); + glDrawArrays(GL_TRIANGLES, 0, 6 * glyphs.size()); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index ce66e4b..9f84a25 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -100,7 +100,6 @@ public: virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor); virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); - void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti); Type type() const { return OpenGL; } -- cgit v0.12 From d903f379470fb9f9159fbf37f2cfc02638cd05f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 18 Feb 2009 14:54:51 +0100 Subject: Fixes: Enable use of the GL pixmap backend in the GL 2 paint engine. --- src/opengl/qgl.cpp | 10 +++++----- src/opengl/qgl_p.h | 4 ++++ src/opengl/qpixmapdata_gl.cpp | 13 ++++++++++--- src/opengl/qpixmapdata_gl_p.h | 1 + 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 7c42039..558897d 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1888,14 +1888,14 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint /*! \internal */ GLuint QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean) { -#if !defined(QT_OPENGL_ES_2) - if (target == qt_gl_preferredTextureTarget() && pixmap.pixmapData()->classId() == QPixmapData::OpenGLClass) { - const QGLPixmapData *data = static_cast(pixmap.pixmapData()); + Q_Q(QGLContext); + QPixmapData *pd = pixmap.pixmapData(); + if (target == qt_gl_preferredTextureTarget() && pd->classId() == QPixmapData::OpenGLClass) { + const QGLPixmapData *data = static_cast(pd); - if (data->isValidContext(QGLContext::currentContext())) + if (data->isValidContext(q)) return data->bind(); } -#endif const qint64 key = pixmap.cacheKey(); GLuint id; diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 2eccc23..76f3812 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -418,9 +418,13 @@ inline GLenum qt_gl_preferredTextureFormat() inline GLenum qt_gl_preferredTextureTarget() { +#if 1 || defined(QT_OPENGL_ES_2) + return GL_TEXTURE_2D; +#else return (QGLExtensions::glExtensions & QGLExtensions::TextureRectangle) ? GL_TEXTURE_RECTANGLE_NV : GL_TEXTURE_2D; +#endif } diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index b079557..ec71fa6 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -57,12 +57,14 @@ class QGLShareContextScope public: QGLShareContextScope(const QGLContext *ctx) : m_oldContext(0) - , m_ctx(const_cast(ctx)) { - const QGLContext *currentContext = QGLContext::currentContext(); + QGLContext *currentContext = const_cast(QGLContext::currentContext()); if (currentContext != ctx && !qgl_share_reg()->checkSharing(ctx, currentContext)) { - m_oldContext = const_cast(currentContext); + m_oldContext = currentContext; + m_ctx = const_cast(ctx); m_ctx->makeCurrent(); + } else { + m_ctx = currentContext; } } @@ -127,6 +129,7 @@ QGLPixmapData::QGLPixmapData(PixelType type) : QPixmapData(type, OpenGLClass) , m_width(0) , m_height(0) + , m_ctx(0) , m_texture(0) , m_dirty(false) { @@ -148,6 +151,9 @@ bool QGLPixmapData::isValid() const bool QGLPixmapData::isValidContext(const QGLContext *ctx) const { + if (ctx == m_ctx) + return true; + const QGLContext *share_ctx = qt_gl_share_widget()->context(); return ctx == share_ctx || qgl_share_reg()->checkSharing(ctx, share_ctx); } @@ -173,6 +179,7 @@ void QGLPixmapData::ensureCreated() const m_dirty = false; QGLShareContextScope ctx(qt_gl_share_widget()->context()); + m_ctx = ctx; const GLenum format = qt_gl_preferredTextureFormat(); const GLenum target = qt_gl_preferredTextureTarget(); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index e450f01..97f4959 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -97,6 +97,7 @@ private: int m_width; int m_height; + mutable QGLContext *m_ctx; mutable GLuint m_texture; mutable bool m_dirty; mutable QImage m_source; -- cgit v0.12 From a3c964db2bee664b0e71e9ec1c5d8b2830659ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 18 Feb 2009 14:56:16 +0100 Subject: Fixes: Introduce mode transfer functions in the GL 2 paint engine. RevBy: Tom Details: Mode transfer lets us optimize the case where the same operation is done a lot of times in a row, for example image or text drawing, by being able to assume that most of the state has already been set up properly. --- src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h | 4 +- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 143 +++++++++++++-------- 2 files changed, 94 insertions(+), 53 deletions(-) diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index 65f6d42..a83f13e 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -62,7 +62,7 @@ public: QGLPoint(GLfloat new_x, GLfloat new_y) : x(new_x), y(new_y) {}; - QGLPoint(QPointF p) : + QGLPoint(const QPointF &p) : x(p.x()), y(p.y()) {}; QGLPoint(const QPointF* p) : @@ -77,7 +77,7 @@ public: struct QGLRect { - QGLRect(QRectF r) + QGLRect(const QRectF &r) : left(r.left()), top(r.top()), right(r.right()), bottom(r.bottom()) {} QGLRect(GLfloat l, GLfloat t, GLfloat r, GLfloat b) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index ea0d7b1..88c33d4 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -86,6 +86,11 @@ extern QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp #include +enum EngineMode { + ImageDrawingMode, + TextDrawingMode, + DefaultMode +}; static const GLuint QT_VERTEX_COORDS_ATTR = 0; static const GLuint QT_TEXTURE_COORDS_ATTR = 1; @@ -114,7 +119,9 @@ public: void setBrush(const QBrush* brush); - void drawTexture(const QGLRect& dest, const QGLRect& src, int txtWidth, int txtHeight); + void transferMode(EngineMode newMode); + + void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize); void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti); void fill(const QVectorPath &path); @@ -138,6 +145,8 @@ public: int width, height; QGLContext *ctx; + EngineMode mode; + // Dirty flags bool matrixDirty; // Implies matrix uniforms are also dirty bool compositionModeDirty; @@ -156,6 +165,9 @@ public: QGL2PEXVertexArray vertexCoordinateArray; QGL2PEXVertexArray textureCoordinateArray; + GLfloat staticVertexCoordinateArray[8]; + GLfloat staticTextureCoordinateArray[8]; + GLfloat pmvMatrix[4][4]; QGLPEXShaderManager* shaderManager; @@ -486,14 +498,21 @@ void QGL2PaintEngineExPrivate::updateCompositionMode() compositionModeDirty = false; } +static inline void setCoords(GLfloat *coords, const QGLRect &rect) +{ + coords[0] = rect.left; + coords[1] = rect.top; + coords[2] = rect.right; + coords[3] = rect.top; + coords[4] = rect.right; + coords[5] = rect.bottom; + coords[6] = rect.left; + coords[7] = rect.bottom; +} -void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, int txtWidth, int txtHeight) +void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize) { // qDebug("QGL2PaintEngineExPrivate::drawImage()"); - - // We have a shader specifically for drawPixmap/drawImage... - shaderManager->imageShader()->use(); - updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); if (compositionModeDirty) @@ -507,45 +526,66 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s imageShaderMatrixUniformDirty = false; } - shaderManager->imageShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; - -// if (q->state()->opacity < 0.99f) + if (q->state()->opacity < 0.99f) shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)q->state()->opacity; - GLfloat vertexCoords[] = { - dest.left, dest.top, - dest.left, dest.bottom, - dest.right, dest.bottom, - dest.right, dest.top - }; + GLfloat dx = 1.0 / textureSize.width(); + GLfloat dy = 1.0 / textureSize.height(); - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoords); + QGLRect srcTextureRect(src.left*dx, 1.0 - src.top*dy, src.right*dx, 1.0 - src.bottom*dy); - GLfloat dx = 1.0 / txtWidth; - GLfloat dy = 1.0 / txtHeight; + setCoords(staticVertexCoordinateArray, dest); + setCoords(staticTextureCoordinateArray, srcTextureRect); - QGLRect srcTextureRect(src.left*dx, 1.0 - src.top*dy, src.right*dx, 1.0 - src.bottom*dy); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} - GLfloat textureCoords[] = { - srcTextureRect.left, srcTextureRect.top, - srcTextureRect.left, srcTextureRect.bottom, - srcTextureRect.right, srcTextureRect.bottom, - srcTextureRect.right, srcTextureRect.top - }; +void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) +{ + if (newMode == mode) + return; - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + if (mode == TextDrawingMode || mode == ImageDrawingMode) { + glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); + glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); + } - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + if (newMode == TextDrawingMode) { + glEnable(GL_BLEND); + glActiveTexture(QT_BRUSH_TEXTURE_UNIT); - glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); -} + glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); + glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); + glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); + + shaderManager->textShader()->use(); + shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; + } + + if (newMode == ImageDrawingMode) { + // We have a shader specifically for drawPixmap/drawImage... + shaderManager->imageShader()->use(); + shaderManager->imageShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; + shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)1.0; + + glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); + glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); + + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticVertexCoordinateArray); + glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticTextureCoordinateArray); + + glActiveTexture(QT_BRUSH_TEXTURE_UNIT); + } + + mode = newMode; +} void QGL2PaintEngineExPrivate::drawOutline(const QVectorPath& path) { + transferMode(DefaultMode); + // qDebug("QGL2PaintEngineExPrivate::drawOutline()"); if (matrixDirty) updateMatrix(); @@ -567,6 +607,8 @@ void QGL2PaintEngineExPrivate::drawOutline(const QVectorPath& path) // Assumes everything is configured for the brush you want to use void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) { + transferMode(DefaultMode); + if (matrixDirty) updateMatrix(); @@ -846,10 +888,10 @@ void QGL2PaintEngineEx::transformChanged() void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src) { Q_D(QGL2PaintEngineEx); - QGLContext *ctx = d->ctx; - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); + d->transferMode(ImageDrawingMode); - d->ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true); + QGLContext *ctx = d->ctx; + ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true); //FIXME: we should use hasAlpha() instead, but that's SLOW at the moment if ((state()->opacity < 0.99f) || pixmap.hasAlphaChannel()) @@ -857,23 +899,24 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c else glDisable(GL_BLEND); - d->drawTexture(dest, src, pixmap.width(), pixmap.height()); + d->drawTexture(dest, src, pixmap.size()); } void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src, Qt::ImageConversionFlags) { Q_D(QGL2PaintEngineEx); + d->transferMode(ImageDrawingMode); + QGLContext *ctx = d->ctx; - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); - d->ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); + ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); if ((state()->opacity < 0.99f) || image.hasAlphaChannel()) glEnable(GL_BLEND); else glDisable(GL_BLEND); - d->drawTexture(dest, src, image.width(), image.height()); + d->drawTexture(dest, src, image.size()); } void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem) @@ -908,6 +951,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte Q_Q(QGL2PaintEngineEx); QOpenGLPaintEngineState *s = q->state(); + transferMode(TextDrawingMode); + QVarLengthArray positions; QVarLengthArray glyphs; QTransform matrix; @@ -930,12 +975,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte const QImage &image = cache->image(); int margin = cache->glyphMargin(); - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); - glEnable(GL_BLEND); - - shaderManager->textShader()->use(); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); if (compositionModeDirty) @@ -949,13 +990,15 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte textShaderMatrixUniformDirty = false; } - shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; QColor col = premultiplyColor(s->pen.color(), (GLfloat)s->opacity); shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col; GLfloat dx = 1.0 / image.width(); GLfloat dy = 1.0 / image.height(); + QGLPoint *oldVertexCoordinateDataPtr = vertexCoordinateArray.data(); + QGLPoint *oldTextureCoordinateDataPtr = textureCoordinateArray.data(); + vertexCoordinateArray.clear(); textureCoordinateArray.clear(); @@ -968,15 +1011,12 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte textureCoordinateArray.addRect(QRectF(c.x*dx, 1 - c.y*dy, c.w * dx, -c.h * dy)); } - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); + if (vertexCoordinateArray.data() != oldVertexCoordinateDataPtr) + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); + if (textureCoordinateArray.data() != oldTextureCoordinateDataPtr) + glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); - glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); glDrawArrays(GL_TRIANGLES, 0, 6 * glyphs.size()); - - glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); } bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) @@ -991,6 +1031,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) QSize sz = d->drawable.size(); d->width = sz.width(); d->height = sz.height(); + d->mode = DefaultMode; qt_resolve_version_1_3_functions(d->ctx); qt_resolve_glsl_extensions(d->ctx); -- cgit v0.12 From 7cee2659388388754d741ba4b46647c57d03c498 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 23 Feb 2009 13:54:07 +0100 Subject: Fixes: Make raster engine perform better on 0-opacity drawing RevBy: sroedal Task: came in from brisbane --- src/gui/painting/qdrawhelper_p.h | 3 ++- src/gui/painting/qpaintengine_raster.cpp | 23 +++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index de97683..586ffe3 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -110,6 +110,7 @@ struct QSpanData; class QGradient; class QRasterBuffer; class QClipData; +class QRasterPaintEngineState; typedef QT_FT_SpanFunc ProcessSpans; typedef void (*BitmapBlitFunc)(QRasterBuffer *rasterBuffer, @@ -293,7 +294,7 @@ struct QSpanData }; void init(QRasterBuffer *rb, const QRasterPaintEngine *pe); - void setup(const QBrush &brush, int alpha); + void setup(const QBrush &brush, int alpha, const QRasterPaintEngineState *s); void setupMatrix(const QTransform &matrix, int bilinear); void initTexture(const QImage *image, int alpha, QTextureData::Type = QTextureData::Plain, const QRect &sourceRect = QRect()); void adjustSpanMethods(); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index ba79b5b..92a196c 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -483,12 +483,12 @@ bool QRasterPaintEngine::begin(QPaintDevice *device) d->rasterizer->setClipRect(d->deviceRect); s->penData.init(d->rasterBuffer, this); - s->penData.setup(s->pen.brush(), s->intOpacity); + s->penData.setup(s->pen.brush(), s->intOpacity, s); s->stroker = &d->basicStroker; d->basicStroker.setClipRect(d->deviceRect); s->brushData.init(d->rasterBuffer, this); - s->brushData.setup(s->brush, s->intOpacity); + s->brushData.setup(s->brush, s->intOpacity, s); d->rasterBuffer->compositionMode = QPainter::CompositionMode_SourceOver; @@ -769,7 +769,7 @@ void QRasterPaintEngine::updatePen(const QPen &pen) s->strokeFlags = 0; s->penData.clip = d->clip(); - s->penData.setup(pen_style == Qt::NoPen ? QBrush() : pen.brush(), s->intOpacity); + s->penData.setup(pen_style == Qt::NoPen ? QBrush() : pen.brush(), s->intOpacity, s); if (s->strokeFlags & QRasterPaintEngine::DirtyTransform || pen.brush().transform().type() >= QTransform::TxNone) { @@ -869,7 +869,7 @@ void QRasterPaintEngine::updateBrush(const QBrush &brush) QRasterPaintEngineState *s = state(); // must set clip prior to setup, as setup uses it... s->brushData.clip = d->clip(); - s->brushData.setup(brush, s->intOpacity); + s->brushData.setup(brush, s->intOpacity, s); if (s->fillFlags & DirtyTransform || brush.transform().type() >= QTransform::TxNone) d_func()->updateMatrixData(&s->brushData, brush, d->brushMatrix()); @@ -1024,6 +1024,10 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt, { if (!clip.isValid()) return; + + if (alpha ==0) + return; + Q_ASSERT(img.depth() >= 8); int srcBPL = img.bytesPerLine(); @@ -1867,9 +1871,12 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color) QRasterPaintEngineState *s = state(); d->solid_color_filler.solid.color = PREMUL(ARGB_COMBINE_ALPHA(color.rgba(), s->intOpacity)); + if ((d->solid_color_filler.solid.color & 0xff000000) == 0 + && s->composition_mode == QPainter::CompositionMode_SourceOver) { + return; + } d->solid_color_filler.clip = d->clip(); d->solid_color_filler.adjustSpanMethods(); - fillRect(r, &d->solid_color_filler); } @@ -4906,7 +4913,7 @@ void QSpanData::init(QRasterBuffer *rb, const QRasterPaintEngine *pe) extern QImage qt_imageForBrush(int brushStyle, bool invert); -void QSpanData::setup(const QBrush &brush, int alpha) +void QSpanData::setup(const QBrush &brush, int alpha, const QRasterPaintEngineState *s) { Qt::BrushStyle brushStyle = qbrush_style(brush); switch (brushStyle) { @@ -4914,6 +4921,10 @@ void QSpanData::setup(const QBrush &brush, int alpha) type = Solid; QColor c = qbrush_color(brush); solid.color = PREMUL(ARGB_COMBINE_ALPHA(c.rgba(), alpha)); + if ((solid.color & 0xff000000) == 0 + && s->composition_mode == QPainter::CompositionMode_SourceOver) { + type = None; + } break; } -- cgit v0.12 From 6ab74831766cdd5cf4e94eee8a60099436e61202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 9 Mar 2009 13:07:18 +0100 Subject: Fixes: Extreme amount of pixel buffers created in embeddeddialogs demo. Details: As a window surface is created even for embedded widgets, don't create the GL resources required by the surface until they are actually needed. RevBy: Tom --- src/opengl/qwindowsurface_gl.cpp | 14 +++++++++++--- src/opengl/qwindowsurface_gl_p.h | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index bb4ffc5..08c2aab 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -315,6 +315,8 @@ QGLContext *QGLWindowSurface::context() const QPaintDevice *QGLWindowSurface::paintDevice() { + updateGeometry(); + if (d_ptr->pb) return d_ptr->pb; @@ -330,6 +332,7 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, void QGLWindowSurface::beginPaint(const QRegion &) { + updateGeometry(); } void QGLWindowSurface::endPaint(const QRegion &rgn) @@ -460,9 +463,9 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & d_ptr->fbo->bind(); } -void QGLWindowSurface::setGeometry(const QRect &rect) +void QGLWindowSurface::updateGeometry() { - QWindowSurface::setGeometry(rect); + QRect rect = QWindowSurface::geometry(); const GLenum target = qt_gl_preferredTextureTarget(); @@ -496,7 +499,7 @@ void QGLWindowSurface::setGeometry(const QRect &rect) qt_gl_share_widget()); if (d_ptr->pb->isValid()) { - qDebug() << "PB Sample buffers:" << d_ptr->pb->format().sampleBuffers(); + qDebug() << "Created Window Surface Pixelbuffer, Sample buffers:" << d_ptr->pb->format().sampleBuffers(); d_ptr->pb->makeCurrent(); glGenTextures(1, &d_ptr->pb_tex_id); @@ -561,6 +564,11 @@ void QGLWindowSurface::setGeometry(const QRect &rect) d_ptr->ctx->d_ptr->internal_context = true; } +void QGLWindowSurface::setGeometry(const QRect &rect) +{ + QWindowSurface::setGeometry(rect); +} + bool QGLWindowSurface::scroll(const QRegion &area, int dx, int dy) { // this code randomly fails currently for unknown reasons diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h index 0194378..d47e3e3 100644 --- a/src/opengl/qwindowsurface_gl_p.h +++ b/src/opengl/qwindowsurface_gl_p.h @@ -74,6 +74,7 @@ public: QPaintDevice *paintDevice(); void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); void setGeometry(const QRect &rect); + void updateGeometry(); bool scroll(const QRegion &area, int dx, int dy); void beginPaint(const QRegion ®ion); -- cgit v0.12 From 570ef6dbc4526d39ef8d2b7e29ddedcfa67b061f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 9 Mar 2009 15:01:48 +0100 Subject: Fixes: Clipping bug in GL 2 paint engine (embeddeddialogs demo). RevBy: Tom --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 88c33d4..9eeef1b 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1057,6 +1057,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) glDisable(GL_DEPTH_TEST); + updateClipRegion(QRegion(), Qt::NoClip); return true; } -- cgit v0.12 From 0f95b04c91e559ca62698234dcd82445c5ee8ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 9 Mar 2009 15:01:16 +0100 Subject: Fixes: Small optimizations in GL 2 paint engine... RevBy: Tom --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 9eeef1b..ce9f976 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -424,7 +424,9 @@ void QGL2PaintEngineExPrivate::updateMatrix() for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { pmvMatrix[col][row] = 0.0; - for (int n = 0; n < 4; ++n) + + // P[row][n] is 0.0 for n < row + for (int n = row; n < 4; ++n) pmvMatrix[col][row] += P[row][n] * MV[n][col]; } } @@ -804,8 +806,6 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QGL2PaintEngineEx); - QTime startTime = QTime::currentTime(); - d->setBrush(&brush); d->fill(path); d->setBrush(&(state()->brush)); // reset back to the state's brush -- cgit v0.12 From 4feeae36f1dc18795646e648f9987795706d21f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 9 Mar 2009 13:09:25 +0100 Subject: Fixes: Get rid of GL 2 paint engine debug message... RevBy: Tom --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index ce9f976..6e24bdc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -794,8 +794,6 @@ void QGL2PaintEngineExPrivate::drawVertexArrays(QGL2PEXVertexArray& vertexArray, QGL2PaintEngineEx::QGL2PaintEngineEx() : QPaintEngineEx(*(new QGL2PaintEngineExPrivate(this))) { - qDebug("QGL2PaintEngineEx::QGL2PaintEngineEx()"); - } QGL2PaintEngineEx::~QGL2PaintEngineEx() -- cgit v0.12 From 56fc9b853f8d19999c81ed13a9f2fcd0e95241e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 11 Mar 2009 09:16:37 +0100 Subject: Fixes: Respect the SmoothPixmapTransform render hint in the GL2 paint engine. RevBy: Tom --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 6e24bdc..dbf18b1 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -515,7 +515,7 @@ static inline void setCoords(GLfloat *coords, const QGLRect &rect) void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize) { // qDebug("QGL2PaintEngineExPrivate::drawImage()"); - updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); + updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); if (compositionModeDirty) updateCompositionMode(); -- cgit v0.12 From 4d4580b5f43adb22b6ba95f49698efcd5dbdfeae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 11 Mar 2009 10:37:13 +0100 Subject: Fixes: Make FBO window surface work with GL 2 paint engine. RevBy: Trond Details: Need to make sure clipping/scissoring etc is turned off and that we are in a good state. --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 3 +++ src/opengl/qwindowsurface_gl.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index dbf18b1..89ed1f7 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1062,6 +1062,9 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) bool QGL2PaintEngineEx::end() { Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; + glUseProgram(0); + d->transferMode(DefaultMode); d->drawable.swapBuffers(); d->drawable.doneCurrent(); return false; diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 08c2aab..5cd4366 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -439,6 +439,9 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & if (d_ptr->fbo) d_ptr->fbo->release(); + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); @@ -539,6 +542,7 @@ void QGLWindowSurface::updateGeometry() d_ptr->fbo->bind(); if (d_ptr->fbo->isValid()) { + qDebug() << "Created Window Surface FBO" << rect.size(); return; } else { qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back"; -- cgit v0.12 From 1ada6800efbbca276441b3b170b1ccfa0c09c20a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 12 Mar 2009 09:00:34 +0100 Subject: Fixes: Add blitting and multisample API to QGLFramebufferObject. RevBy: Trond Details: Support GL_EXT_framebuffer_multisample and GL_EXT_framebuffer_blit in the QGLFramebufferObject API. --- src/opengl/qgl.cpp | 2 + src/opengl/qgl_p.h | 3 +- src/opengl/qglextensions.cpp | 3 + src/opengl/qglextensions_p.h | 37 +++ src/opengl/qglframebufferobject.cpp | 456 +++++++++++++++++++++++++++++++++--- src/opengl/qglframebufferobject.h | 49 ++++ 6 files changed, 520 insertions(+), 30 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 558897d..fc11d90 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4175,6 +4175,8 @@ void QGLExtensions::init_extensions() glExtensions |= FramebufferObject; glExtensions |= GenerateMipmap; #endif + if (extensions.contains(QLatin1String("EXT_framebuffer_blit"))) + glExtensions |= FramebufferBlit; QGLContext cx(QGLFormat::defaultFormat()); if (glExtensions & TextureCompression) { diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 76f3812..8ab73d8 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -330,7 +330,8 @@ public: StencilWrap = 0x00000100, PackedDepthStencil = 0x00000200, NVFloatBuffer = 0x00000400, - PixelBufferObject = 0x00000800 + PixelBufferObject = 0x00000800, + FramebufferBlit = 0x00001000 }; Q_DECLARE_FLAGS(Extensions, Extension) diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp index b054fe8..e6ac043 100644 --- a/src/opengl/qglextensions.cpp +++ b/src/opengl/qglextensions.cpp @@ -74,6 +74,9 @@ bool qt_resolve_framebufferobject_extensions(QGLContext *ctx) glGetFramebufferAttachmentParameterivEXT = (_glGetFramebufferAttachmentParameterivEXT) ctx->getProcAddress(QLatin1String("glGetFramebufferAttachmentParameterivEXT")); glGenerateMipmapEXT = (_glGenerateMipmapEXT) ctx->getProcAddress(QLatin1String("glGenerateMipmapEXT")); + glBlitFramebufferEXT = (_glBlitFramebufferEXT) ctx->getProcAddress(QLatin1String("glBlitFramebufferEXT")); + glRenderbufferStorageMultisampleEXT = + (_glRenderbufferStorageMultisampleEXT) ctx->getProcAddress(QLatin1String("glRenderbufferStorageMultisampleEXT")); return glIsRenderbufferEXT; #else Q_UNUSED(ctx); diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index fdf0bba..cd35eb0 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -162,6 +162,15 @@ typedef void (APIENTRY *_glGetFramebufferAttachmentParameterivEXT) (GLenum targe GLint *params); typedef void (APIENTRY *_glGenerateMipmapEXT) (GLenum target); +// EXT_GL_framebuffer_blit +typedef void (APIENTRY *_glBlitFramebufferEXT) (int srcX0, int srcY0, int srcX1, int srcY1, + int dstX0, int dstY0, int dstX1, int dstY1, + GLbitfield mask, GLenum filter); + +// EXT_GL_framebuffer_multisample +typedef void (APIENTRY *_glRenderbufferStorageMultisampleEXT) (GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height); + QT_BEGIN_NAMESPACE struct QGLExtensionFuncs @@ -220,6 +229,8 @@ struct QGLExtensionFuncs qt_glGetFramebufferAttachmentParameterivEXT = 0; qt_glGenerateMipmapEXT = 0; #endif + qt_glBlitFramebufferEXT = 0; + qt_glRenderbufferStorageMultisampleEXT = 0; qt_glBindBufferARB = 0; qt_glDeleteBuffersARB = 0; @@ -298,6 +309,8 @@ struct QGLExtensionFuncs _glGetFramebufferAttachmentParameterivEXT qt_glGetFramebufferAttachmentParameterivEXT; _glGenerateMipmapEXT qt_glGenerateMipmapEXT; #endif + _glBlitFramebufferEXT qt_glBlitFramebufferEXT; + _glRenderbufferStorageMultisampleEXT qt_glRenderbufferStorageMultisampleEXT; _glBindBufferARB qt_glBindBufferARB; _glDeleteBuffersARB qt_glDeleteBuffersARB; @@ -447,6 +460,28 @@ struct QGLExtensionFuncs #define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 #endif +// GL_EXT_framebuffer_blit +#ifndef GL_READ_FRAMEBUFFER_EXT +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#endif + +// GL_EXT_framebuffer_multisample +#ifndef GL_RENDERBUFFER_SAMPLES_EXT +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#endif + +#ifndef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#endif + +#ifndef GL_MAX_SAMPLES_EXT +#define GL_MAX_SAMPLES_EXT 0x8D5 +#endif + +#ifndef GL_DRAW_FRAMEBUFFER_EXT +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#endif + #ifndef GL_EXT_packed_depth_stencil #define GL_DEPTH_STENCIL_EXT 0x84F9 #define GL_UNSIGNED_INT_24_8_EXT 0x84FA @@ -533,6 +568,8 @@ struct QGLExtensionFuncs #define glFramebufferRenderbufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glFramebufferRenderbufferEXT #define glGetFramebufferAttachmentParameterivEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetFramebufferAttachmentParameterivEXT #define glGenerateMipmapEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenerateMipmapEXT +#define glBlitFramebufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBlitFramebufferEXT +#define glRenderbufferStorageMultisampleEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glRenderbufferStorageMultisampleEXT #else // QT_OPENGL_ES_2 diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 9134fc6..297ef84 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -67,6 +67,216 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool); } \ } +class QGLFramebufferObjectFormatPrivate +{ +public: + int samples; + QGLFramebufferObject::Attachment attachment; + GLenum target; + GLenum internal_format; +}; + +/*! + \class QGLFramebufferObjectFormat + \brief The QGLFramebufferObjectFormat class specifies the format of an OpenGL + framebuffer object. + + \since 4.6 + + \ingroup multimedia + + A framebuffer object has several characteristics: + \list + \i \link setSamples() Number of samples per pixels.\endlink + \i \link setAttachment() Depth and/or stencil attachments.\endlink + \i \link setTextureTarget() Texture target.\endlink + \i \link setInternalFormat() Internal format.\endlink + \endlist + + Note that the desired attachments or number of samples per pixels might not + be supported by the hardware driver. Call QGLFramebufferObject::format() + after creating a QGLFramebufferObject to find the exact format that was + used to create the frame buffer object. + + \sa QGLFramebufferObject +*/ + +/*! + \since 4.6 + + Creates a QGLFramebufferObjectFormat object with properties specifying + the format of an OpenGL framebuffer object. + + A multisample framebuffer object is specified by setting \a samples + to a value different from zero. If the desired amount of samples per pixel is + not supported by the hardware then the maximum number of samples per pixel + will be used. Note that multisample framebuffer objects can not be bound as + textures. Also, the \c{GL_EXT_framebuffer_multisample} extension is required + to create a framebuffer with more than one sample per pixel. + + For multisample framebuffer objects a color render buffer is created, + otherwise a texture with the texture target \a target is created. + The color render buffer or texture will have the internal format + \a internalFormat, and will be bound to the \c GL_COLOR_ATTACHMENT0 + attachment in the framebuffer object. + + The \a attachment parameter describes the depth/stencil buffer + configuration. + + \sa samples(), attachment(), target(), internalFormat() +*/ + +QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(int samples, + QGLFramebufferObject::Attachment attachment, + GLenum target, + GLenum internalFormat) +{ + d = new QGLFramebufferObjectFormatPrivate; + d->samples = samples; + d->attachment = attachment; + d->target = target; + d->internal_format = internalFormat; +} + +/*! + \since 4.6 + + Constructs a copy of \a other. +*/ + +QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other) +{ + d = new QGLFramebufferObjectFormatPrivate; + *d = *other.d; +} + +/*! + \since 4.6 + + Assigns \a other to this object. +*/ + +QGLFramebufferObjectFormat::QGLFramebufferObjectFormat & +QGLFramebufferObjectFormat::operator=(const QGLFramebufferObjectFormat &other) +{ + *d = *other.d; + return *this; +} + +/*! + \since 4.6 + + Destroys the QGLFramebufferObjectFormat. +*/ +QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat() +{ + delete d; +} + +/*! + \since 4.6 + + Sets the number of samples per pixel for a multisample framebuffer object + to \a samples. + A sample count of 0 represents a regular non-multisample framebuffer object. + + \sa samples() +*/ +void QGLFramebufferObjectFormat::setSamples(int samples) +{ + d->samples = samples; +} + +/*! + \since 4.6 + + Returns the number of samples per pixel if a framebuffer object + is a multisample framebuffer object. Otherwise, returns 0. + + \sa setSamples() +*/ +int QGLFramebufferObjectFormat::samples() const +{ + return d->samples; +} + +/*! + \since 4.6 + + Sets the attachments a framebuffer object should have to \a attachment. + + \sa attachment() +*/ +void QGLFramebufferObjectFormat::setAttachment(QGLFramebufferObject::Attachment attachment) +{ + d->attachment = attachment; +} + +/*! + \since 4.6 + + Returns the status of the depth and stencil buffers attached to + a framebuffer object. + + \sa setAttachment() +*/ +QGLFramebufferObject::Attachment QGLFramebufferObjectFormat::attachment() const +{ + return d->attachment; +} + +/*! + \since 4.6 + + Sets the texture target of the texture attached to a framebuffer object to + \a target. Ignored for multisample framebuffer objects. + + \sa textureTarget(), samples() +*/ +void QGLFramebufferObjectFormat::setTextureTarget(GLenum target) +{ + d->target = target; +} + +/*! + \since 4.6 + + Returns the texture target of the texture attached to a framebuffer object. + Ignored for multisample framebuffer objects. + + \sa setTextureTarget(), samples() +*/ +GLenum QGLFramebufferObjectFormat::textureTarget() const +{ + return d->target; +} + +/*! + \since 4.6 + + Sets the internal format of a framebuffer object's texture or multisample + framebuffer object's color buffer to \a internalFormat. + + \sa internalFormat() +*/ +void QGLFramebufferObjectFormat::setInternalFormat(GLenum internalFormat) +{ + d->internal_format = internalFormat; +} + +/*! + \since 4.6 + + Returns the internal format of a framebuffer object's texture or + multisample framebuffer object's color buffer. + + \sa setInternalFormat() +*/ +GLenum QGLFramebufferObjectFormat::internalFormat() const +{ + return d->internal_format; +} + class QGLFramebufferObjectPrivate { public: @@ -74,13 +284,16 @@ public: ~QGLFramebufferObjectPrivate() {} void init(const QSize& sz, QGLFramebufferObject::Attachment attachment, - GLenum internal_format, GLenum texture_target); + GLenum internal_format, GLenum texture_target, int samples = 0); bool checkFramebufferStatus() const; GLuint texture; GLuint fbo; GLuint depth_stencil_buffer; + GLuint color_buffer; GLenum target; QSize size; + QGLFramebufferObjectFormat format; + int samples; uint valid : 1; uint bound : 1; QGLFramebufferObject::Attachment fbo_attachment; @@ -122,6 +335,9 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: qDebug("QGLFramebufferObject: Framebuffer incomplete, missing read buffer."); break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: + qDebug("QGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel."); + break; default: qDebug() <<"QGLFramebufferObject: An undefined error has occurred: "<< status; break; @@ -130,7 +346,7 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const } void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::Attachment attachment, - GLenum texture_target, GLenum internal_format) + GLenum texture_target, GLenum internal_format, int samples) { ctx = const_cast(QGLContext::currentContext()); bool ext_detected = (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject); @@ -147,26 +363,56 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At QT_CHECK_GLERROR(); // init texture - glGenTextures(1, &texture); - glBindTexture(target, texture); - glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + if (samples == 0) { + glGenTextures(1, &texture); + glBindTexture(target, texture); + glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); #ifndef QT_OPENGL_ES - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #else - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #endif - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - target, texture, 0); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + target, texture, 0); - QT_CHECK_GLERROR(); - valid = checkFramebufferStatus(); + QT_CHECK_GLERROR(); + valid = checkFramebufferStatus(); + + color_buffer = 0; + samples = 0; + } else { + GLint maxSamples; + glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); + + samples = qBound(1, samples, int(maxSamples)); + + glGenRenderbuffersEXT(1, &color_buffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, color_buffer); + if (glRenderbufferStorageMultisampleEXT) { + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + internal_format, size.width(), size.height()); + } else { + samples = 0; + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internal_format, + size.width(), size.height()); + } + + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, color_buffer); + + QT_CHECK_GLERROR(); + valid = checkFramebufferStatus(); + + if (valid) + glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples); + } if (attachment == QGLFramebufferObject::CombinedDepthStencil && (QGLExtensions::glExtensions & QGLExtensions::PackedDepthStencil)) { @@ -175,7 +421,13 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At Q_ASSERT(!glIsRenderbufferEXT(depth_stencil_buffer)); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer); Q_ASSERT(glIsRenderbufferEXT(depth_stencil_buffer)); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); + if (samples != 0 && glRenderbufferStorageMultisampleEXT) + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); + else + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); + GLint i = 0; glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, @@ -183,6 +435,7 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_buffer); fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; + valid = checkFramebufferStatus(); if (!valid) glDeleteRenderbuffersEXT(1, &depth_stencil_buffer); @@ -193,12 +446,23 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At Q_ASSERT(!glIsRenderbufferEXT(depth_stencil_buffer)); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer); Q_ASSERT(glIsRenderbufferEXT(depth_stencil_buffer)); + if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES #define GL_DEPTH_COMPONENT16 0x81A5 - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height()); + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + GL_DEPTH_COMPONENT16, size.width(), size.height()); #else - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + GL_DEPTH_COMPONENT, size.width(), size.height()); #endif + } else { +#ifdef QT_OPENGL_ES +#define GL_DEPTH_COMPONENT16 0x81A5 + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height()); +#else + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); +#endif + } GLint i = 0; glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, @@ -213,10 +477,18 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); if (!valid) { - glDeleteTextures(1, &texture); + if (color_buffer) + glDeleteRenderbuffersEXT(1, &color_buffer); + else + glDeleteTextures(1, &texture); glDeleteFramebuffersEXT(1, &fbo); } QT_CHECK_GLERROR(); + + format.setTextureTarget(target); + format.setSamples(samples); + format.setAttachment(fbo_attachment); + format.setInternalFormat(internal_format); } /*! @@ -264,13 +536,18 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At framebuffer objects more portable. \endlist - Note that primitives drawn to a QGLFramebufferObject with QPainter - will only be antialiased if the QPainter::HighQualityAntialiasing - render hint is set. This is because there is currently no support - for the \c{GL_EXT_framebuffer_multisample} extension, which is - required to do multisample based antialiasing. Also note that the - QPainter::HighQualityAntialiasing render hint requires the - \c{GL_ARB_fragment_program} extension to work in OpenGL. + Note that you need to create a QGLFramebufferObject with more than one + sample per pixel for primitives to be antialiased when drawing using a + QPainter, unless if the QPainter::HighQualityAntialiasing render hint is + set. The QPainter::HighQualityAntialiasing render hint will enable + antialiasing as long as the \c{GL_ARB_fragment_program} extension is + present. To create a multisample framebuffer object you should use one of + the constructors that take a QGLFramebufferObject parameter, and set the + QGLFramebufferObject::samples() property to a non-zero value. + + If you want to use a framebuffer object with multisampling enabled + as a texture, you first need to copy from it to a regular framebuffer + object using QGLContext::blitFramebuffer(). \sa {Framebuffer Object Example} */ @@ -358,6 +635,32 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target) d->init(QSize(width, height), NoAttachment, target, DEFAULT_FORMAT); } +/*! \overload + + Constructs an OpenGL framebuffer object of the given \a size based on the + supplied \a format. +*/ + +QGLFramebufferObject::QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format) + : d_ptr(new QGLFramebufferObjectPrivate) +{ + Q_D(QGLFramebufferObject); + d->init(size, format.attachment(), format.textureTarget(), format.internalFormat(), format.samples()); +} + +/*! \overload + + Constructs an OpenGL framebuffer object of the given \a width and \a height + based on the supplied \a format. +*/ + +QGLFramebufferObject::QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format) + : d_ptr(new QGLFramebufferObjectPrivate) +{ + Q_D(QGLFramebufferObject); + d->init(QSize(width, height), format.attachment(), format.textureTarget(), format.internalFormat(), format.samples()); +} + #ifdef Q_MAC_COMPAT_GL_FUNCTIONS /*! \internal */ QGLFramebufferObject::QGLFramebufferObject(int width, int height, QMacCompatGLenum target) @@ -445,6 +748,8 @@ QGLFramebufferObject::~QGLFramebufferObject() || qgl_share_reg()->checkSharing(d->ctx, QGLContext::currentContext()))) { glDeleteTextures(1, &d->texture); + if (d->color_buffer) + glDeleteRenderbuffersEXT(1, &d->color_buffer); if (d->depth_stencil_buffer) glDeleteRenderbuffersEXT(1, &d->depth_stencil_buffer); glDeleteFramebuffersEXT(1, &d->fbo); @@ -540,6 +845,9 @@ bool QGLFramebufferObject::release() Returns the texture id for the texture attached as the default rendering target in this framebuffer object. This texture id can be bound as a normal texture in your own GL code. + + If a multisample framebuffer object is used then the value returned + from this function will be invalid. */ GLuint QGLFramebufferObject::texture() const { @@ -560,6 +868,15 @@ QSize QGLFramebufferObject::size() const } /*! + Returns the format of this framebuffer object. +*/ +const QGLFramebufferObjectFormat &QGLFramebufferObject::format() const +{ + Q_D(const QGLFramebufferObject); + return d->format; +} + +/*! \fn QImage QGLFramebufferObject::toImage() const Returns the contents of this framebuffer object as a QImage. @@ -752,4 +1069,85 @@ bool QGLFramebufferObject::isBound() const return d->bound; } +/*! + \fn bool QGLFramebufferObject::hasOpenGLFramebufferBlit() + + \since 4.6 + + Returns true if the OpenGL \c{GL_EXT_framebuffer_blit} extension + is present on this system; otherwise returns false. +*/ +bool QGLFramebufferObject::hasOpenGLFramebufferBlit() +{ + QGLWidget dmy; // needed to detect and init the QGLExtensions object + return (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit); +} + +/*! + \since 4.6 + + Blits from the \a sourceRect rectangle in the \a source framebuffer + object to the \a targetRect rectangle in the \a target framebuffer object. + + If \a source or \a target is 0, the default framebuffer will be used + instead of a framebuffer object as source or target respectively. + + The \a buffers parameter should be a mask consisting of any combination of + COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT, and STENCIL_BUFFER_BIT. Any buffer type + that is not present both in the source and target buffers is ignored. + + The \a sourceRect and \a targetRect rectangles may have different sizes; + in this case \a buffers should not contain DEPTH_BUFFER_BIT or + STENCIL_BUFFER_BIT. The \a filter parameter should be set to GL_LINEAR or + GL_NEAREST, and specifies whether linear or nearest interpolation should + be used when scaling is performed. + + If \a source equals \a target a copy is performed within the same buffer. + Results are undefined if the source and target rectangles overlap and + have different sizes. The sizes must also be the same if any of the + framebuffer objects are multisample framebuffers. + + Note that the scissor test will restrict the blit area if enabled. + + This function will have no effect unless hasOpenGLFramebufferBlit() returns + true. +*/ +void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect, + QGLFramebufferObject *source, const QRect &sourceRect, + GLbitfield buffers, + GLenum filter) +{ + if (!(QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit)) + return; + + const QGLContext *ctx = QGLContext::currentContext(); + if (!ctx) + return; + + const int height = ctx->device()->height(); + + const int sh = source ? source->height() : height; + const int th = target ? target->height() : height; + + const int sx0 = sourceRect.left(); + const int sx1 = sourceRect.right(); + const int sy0 = sh - sourceRect.bottom() - 1; + const int sy1 = sh - sourceRect.top() - 1; + + const int tx0 = targetRect.left(); + const int tx1 = targetRect.right(); + const int ty0 = th - targetRect.bottom() - 1; + const int ty1 = th - targetRect.top() - 1; + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source ? source->handle() : 0); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, target ? target->handle() : 0); + + glBlitFramebufferEXT(sx0, sy0, sx1, sy1, + tx0, ty0, tx1, ty1, + buffers, filter); + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); +} + QT_END_NAMESPACE diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h index a9e1b2f..0a2a9d2 100644 --- a/src/opengl/qglframebufferobject.h +++ b/src/opengl/qglframebufferobject.h @@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) class QGLFramebufferObjectPrivate; +class QGLFramebufferObjectFormat; class Q_OPENGL_EXPORT QGLFramebufferObject : public QPaintDevice { @@ -77,6 +78,9 @@ public: GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA); #endif + QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format); + QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format); + #ifdef Q_MAC_COMPAT_GL_FUNCTIONS QGLFramebufferObject(const QSize &size, QMacCompatGLenum target = GL_TEXTURE_2D); QGLFramebufferObject(int width, int height, QMacCompatGLenum target = GL_TEXTURE_2D); @@ -89,10 +93,13 @@ public: virtual ~QGLFramebufferObject(); + const QGLFramebufferObjectFormat &format() const; + bool isValid() const; bool isBound() const; bool bind(); bool release(); + GLuint texture() const; QSize size() const; QImage toImage() const; @@ -110,6 +117,12 @@ public: void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D); #endif + static bool hasOpenGLFramebufferBlit(); + static void blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect, + QGLFramebufferObject *source, const QRect &sourceRect, + GLbitfield buffers = GL_COLOR_BUFFER_BIT, + GLenum filter = GL_NEAREST); + protected: int metric(PaintDeviceMetric metric) const; int devType() const { return QInternal::FramebufferObject; } @@ -120,6 +133,42 @@ private: friend class QGLDrawable; }; +class QGLFramebufferObjectFormatPrivate; +class Q_OPENGL_EXPORT QGLFramebufferObjectFormat +{ +public: +#if !defined(QT_OPENGL_ES) || defined(Q_QDOC) + QGLFramebufferObjectFormat(int samples = 0, + QGLFramebufferObject::Attachment attachment = QGLFramebufferObject::NoAttachment, + GLenum target = GL_TEXTURE_2D, + GLenum internalFormat = GL_RGBA8); +#else + QGLFramebufferObjectFormat(int samples = 0, + QGLFramebufferObject::Attachment attachment = QGLFramebufferObject::NoAttachment, + GLenum target = GL_TEXTURE_2D, + GLenum internalFormat = GL_RGBA); +#endif + + QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other); + QGLFramebufferObjectFormat &operator=(const QGLFramebufferObjectFormat &other); + ~QGLFramebufferObjectFormat(); + + void setSamples(int samples); + int samples() const; + + void setAttachment(QGLFramebufferObject::Attachment attachment); + QGLFramebufferObject::Attachment attachment() const; + + void setTextureTarget(GLenum target); + GLenum textureTarget() const; + + void setInternalFormat(GLenum internalFormat); + GLenum internalFormat() const; + +private: + QGLFramebufferObjectFormatPrivate *d; +}; + QT_END_NAMESPACE QT_END_HEADER -- cgit v0.12 From ee8949183917ae7494cbf0121922d0b68384f90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 11 Mar 2009 12:23:51 +0100 Subject: Fixes: Use the new framebuffer blit/multisample API in the window surface. RevBy: Trond --- src/opengl/qwindowsurface_gl.cpp | 49 +++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 5cd4366..b4a4565 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -436,34 +436,39 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & #ifdef Q_WS_MAC ctx->updatePaintDevice(); #endif - if (d_ptr->fbo) - d_ptr->fbo->release(); - glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + if (d_ptr->fbo && QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) { + QGLFramebufferObject::blitFramebuffer(0, rect, d_ptr->fbo, rect); + d_ptr->fbo->bind(); + } else { + if (d_ptr->fbo) + d_ptr->fbo->release(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); #ifndef QT_OPENGL_ES - glOrtho(0, size.width(), size.height(), 0, -999999, 999999); + glOrtho(0, size.width(), size.height(), 0, -999999, 999999); #else - glOrthof(0, size.width(), size.height(), 0, -999999, 999999); + glOrthof(0, size.width(), size.height(), 0, -999999, 999999); #endif - glViewport(0, 0, size.width(), size.height()); + glViewport(0, 0, size.width(), size.height()); + + glColor4f(1, 1, 1, 1); + drawTexture(rect, texture, window()->size(), br); - glColor4f(1, 1, 1, 1); - drawTexture(rect, texture, window()->size(), br); + if (d_ptr->fbo) + d_ptr->fbo->bind(); + } if (ctx->format().doubleBuffer()) ctx->swapBuffers(); else glFlush(); - - if (d_ptr->fbo) - d_ptr->fbo->bind(); } void QGLWindowSurface::updateGeometry() @@ -537,12 +542,20 @@ void QGLWindowSurface::updateGeometry() ctx->d_ptr->internal_context = true; ctx->makeCurrent(); delete d_ptr->fbo; - d_ptr->fbo = new QGLFramebufferObject(rect.size(), QGLFramebufferObject::CombinedDepthStencil, - GLenum(target), GLenum(GL_RGBA)); + QGLFramebufferObjectFormat format; + format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); + format.setInternalFormat(GL_RGBA); + format.setTextureTarget(target); + + if (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) + format.setSamples(8); + + d_ptr->fbo = new QGLFramebufferObject(rect.size(), format); d_ptr->fbo->bind(); if (d_ptr->fbo->isValid()) { - qDebug() << "Created Window Surface FBO" << rect.size(); + qDebug() << "Created Window Surface FBO" << rect.size() + << "with samples" << d_ptr->fbo->format().samples(); return; } else { qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back"; -- cgit v0.12 From b469889f6f9b49f2e52948e3419958b0d8bfc994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 11 Mar 2009 18:46:13 +0100 Subject: Fixes: Prevent QGLFramebufferObject from resetting the current context. RevBy: Trond Details: If there is already an active context we don't need a dummy widget. --- src/opengl/qglframebufferobject.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 297ef84..45d4788 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -918,7 +918,8 @@ QPaintEngine *QGLFramebufferObject::paintEngine() const */ bool QGLFramebufferObject::hasOpenGLFramebufferObjects() { - QGLWidget dmy; // needed to detect and init the QGLExtensions object + if (!QGLContext::currentContext()) + QGLWidget dmy; // needed to detect and init the QGLExtensions object return (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject); } @@ -1079,7 +1080,8 @@ bool QGLFramebufferObject::isBound() const */ bool QGLFramebufferObject::hasOpenGLFramebufferBlit() { - QGLWidget dmy; // needed to detect and init the QGLExtensions object + if (!QGLContext::currentContext()) + QGLWidget dmy; // needed to detect and init the QGLExtensions object return (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit); } -- cgit v0.12 From 860498a1e63bff2b5a52accda92256c36ba5c23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 11 Mar 2009 18:47:47 +0100 Subject: Fixes: Use the blit/multisample FBO API in the framebuffer object example. RevBy: Trond --- examples/opengl/framebufferobject/glwidget.cpp | 28 ++++++++++++++++++++++---- examples/opengl/framebufferobject/glwidget.h | 3 ++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/examples/opengl/framebufferobject/glwidget.cpp b/examples/opengl/framebufferobject/glwidget.cpp index d3591d6..3cb3929 100644 --- a/examples/opengl/framebufferobject/glwidget.cpp +++ b/examples/opengl/framebufferobject/glwidget.cpp @@ -53,7 +53,18 @@ GLWidget::GLWidget(QWidget *parent) { setWindowTitle(tr("OpenGL framebuffer objects")); makeCurrent(); - fbo = new QGLFramebufferObject(1024, 1024); + + if (QGLFramebufferObject::hasOpenGLFramebufferBlit()) { + QGLFramebufferObjectFormat format; + format.setSamples(4); + + render_fbo = new QGLFramebufferObject(512, 512, format); + texture_fbo = new QGLFramebufferObject(512, 512); + } else { + render_fbo = new QGLFramebufferObject(1024, 1024); + texture_fbo = render_fbo; + } + rot_x = rot_y = rot_z = 0.0f; scale = 0.1f; anim = new QTimeLine(750, this); @@ -113,7 +124,9 @@ GLWidget::~GLWidget() { delete[] wave; glDeleteLists(tile_list, 1); - delete fbo; + delete texture_fbo; + if (render_fbo != texture_fbo) + delete render_fbo; } void GLWidget::paintEvent(QPaintEvent *) @@ -129,10 +142,16 @@ void GLWidget::draw() saveGLState(); // render the 'bubbles.svg' file into our framebuffer object - QPainter fbo_painter(fbo); + QPainter fbo_painter(render_fbo); svg_renderer->render(&fbo_painter); fbo_painter.end(); + if (render_fbo != texture_fbo) { + QRect rect(0, 0, render_fbo->width(), render_fbo->height()); + QGLFramebufferObject::blitFramebuffer(texture_fbo, rect, + render_fbo, rect); + } + // draw into the GL widget glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); @@ -145,8 +164,9 @@ void GLWidget::draw() glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, fbo->texture()); + glBindTexture(GL_TEXTURE_2D, texture_fbo->texture()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glEnable(GL_TEXTURE_2D); glEnable(GL_MULTISAMPLE); glEnable(GL_CULL_FACE); diff --git a/examples/opengl/framebufferobject/glwidget.h b/examples/opengl/framebufferobject/glwidget.h index b64cfa8..d97ef78 100644 --- a/examples/opengl/framebufferobject/glwidget.h +++ b/examples/opengl/framebufferobject/glwidget.h @@ -77,6 +77,7 @@ private: QImage logo; QTimeLine *anim; QSvgRenderer *svg_renderer; - QGLFramebufferObject *fbo; + QGLFramebufferObject *render_fbo; + QGLFramebufferObject *texture_fbo; }; -- cgit v0.12 From 855aa89e0ba99f8a0f75d7b31930bab2cefb93f8 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 4 Mar 2009 14:43:58 +0100 Subject: Fixes: make the toNormalizedFillRect function slightly faster RevBy: sroedal --- src/gui/painting/qpaintengine_raster.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 92a196c..3cf618c 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1706,12 +1706,17 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) static inline QRect toNormalizedFillRect(const QRectF &rect) { - const int x1 = qRound(rect.x() + aliasedCoordinateDelta); - const int y1 = qRound(rect.y() + aliasedCoordinateDelta); - const int x2 = qRound(rect.right() + aliasedCoordinateDelta); - const int y2 = qRound(rect.bottom() + aliasedCoordinateDelta); + int x1 = int(rect.x() + aliasedCoordinateDelta); + int y1 = int(rect.y() + aliasedCoordinateDelta); + int x2 = int(rect.right() + aliasedCoordinateDelta); + int y2 = int(rect.bottom() + aliasedCoordinateDelta); - return QRect(x1, y1, x2 - x1, y2 - y1).normalized(); + if (x2 < x1) + qSwap(x1, x2); + if (y2 < y1) + qSwap(y1, y2); + + return QRect(x1, y1, x2 - x1, y2 - y1); } /*! -- cgit v0.12 From 2cb3823e440116f331c0287b29667f7c448e3ed0 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 24 Mar 2009 08:58:57 +1000 Subject: Import shader implementation from before the history cut. --- demos/boxes/boxes.pro | 2 - demos/boxes/glextensions.cpp | 37 - demos/boxes/glextensions.h | 85 - demos/boxes/glshaders.cpp | 266 --- demos/boxes/glshaders.h | 108 -- demos/boxes/scene.cpp | 102 +- demos/boxes/scene.h | 11 +- examples/opengl/hellogl_es2/glwidget.cpp | 391 ++-- examples/opengl/hellogl_es2/glwidget.h | 31 +- src/opengl/gl2paintengineex/qglshader_p.h | 3 +- src/opengl/opengl.pro | 6 +- src/opengl/qglextensions.cpp | 214 ++- src/opengl/qglextensions_p.h | 126 ++ src/opengl/qglpixmapfilter.cpp | 165 +- src/opengl/qglpixmapfilter_p.h | 29 - src/opengl/qglshaderprogram.cpp | 2828 +++++++++++++++++++++++++++++ src/opengl/qglshaderprogram.h | 285 +++ 17 files changed, 3619 insertions(+), 1070 deletions(-) delete mode 100644 demos/boxes/glshaders.cpp delete mode 100644 demos/boxes/glshaders.h create mode 100644 src/opengl/qglshaderprogram.cpp create mode 100644 src/opengl/qglshaderprogram.h diff --git a/demos/boxes/boxes.pro b/demos/boxes/boxes.pro index 6c1a331..a7b19a3 100644 --- a/demos/boxes/boxes.pro +++ b/demos/boxes/boxes.pro @@ -11,7 +11,6 @@ INCLUDEPATH += . HEADERS += 3rdparty/fbm.h \ glbuffers.h \ glextensions.h \ - glshaders.h \ gltrianglemesh.h \ qtbox.h \ roundedbox.h \ @@ -21,7 +20,6 @@ HEADERS += 3rdparty/fbm.h \ SOURCES += 3rdparty/fbm.c \ glbuffers.cpp \ glextensions.cpp \ - glshaders.cpp \ main.cpp \ qtbox.cpp \ roundedbox.cpp \ diff --git a/demos/boxes/glextensions.cpp b/demos/boxes/glextensions.cpp index 59256a8..5f168b6 100644 --- a/demos/boxes/glextensions.cpp +++ b/demos/boxes/glextensions.cpp @@ -47,23 +47,6 @@ bool GLExtensionFunctions::resolve(const QGLContext *context) { bool ok = true; - RESOLVE_GL_FUNC(CreateShaderObjectARB) - RESOLVE_GL_FUNC(ShaderSourceARB) - RESOLVE_GL_FUNC(CompileShaderARB) - RESOLVE_GL_FUNC(GetObjectParameterivARB) - RESOLVE_GL_FUNC(DeleteObjectARB) - RESOLVE_GL_FUNC(GetInfoLogARB) - RESOLVE_GL_FUNC(CreateProgramObjectARB) - RESOLVE_GL_FUNC(AttachObjectARB) - RESOLVE_GL_FUNC(DetachObjectARB) - RESOLVE_GL_FUNC(LinkProgramARB) - RESOLVE_GL_FUNC(UseProgramObjectARB) - RESOLVE_GL_FUNC(GetUniformLocationARB) - RESOLVE_GL_FUNC(Uniform1iARB) - RESOLVE_GL_FUNC(Uniform1fARB) - RESOLVE_GL_FUNC(Uniform4fARB) - RESOLVE_GL_FUNC(UniformMatrix4fvARB) - RESOLVE_GL_FUNC(GenFramebuffersEXT) RESOLVE_GL_FUNC(GenRenderbuffersEXT) RESOLVE_GL_FUNC(BindRenderbufferEXT) @@ -88,26 +71,6 @@ bool GLExtensionFunctions::resolve(const QGLContext *context) return ok; } -bool GLExtensionFunctions::glslSupported() { - return CreateShaderObjectARB - && CreateShaderObjectARB - && ShaderSourceARB - && CompileShaderARB - && GetObjectParameterivARB - && DeleteObjectARB - && GetInfoLogARB - && CreateProgramObjectARB - && AttachObjectARB - && DetachObjectARB - && LinkProgramARB - && UseProgramObjectARB - && GetUniformLocationARB - && Uniform1iARB - && Uniform1fARB - && Uniform4fARB - && UniformMatrix4fvARB; -} - bool GLExtensionFunctions::fboSupported() { return GenFramebuffersEXT && GenRenderbuffersEXT diff --git a/demos/boxes/glextensions.h b/demos/boxes/glextensions.h index 74617d6..4755532 100644 --- a/demos/boxes/glextensions.h +++ b/demos/boxes/glextensions.h @@ -47,23 +47,6 @@ /* Functions resolved: -glCreateShaderObjectARB -glShaderSourceARB -glCompileShaderARB -glGetObjectParameterivARB -glDeleteObjectARB -glGetInfoLogARB -glCreateProgramObjectARB -glAttachObjectARB -glDetachObjectARB -glLinkProgramARB -glUseProgramObjectARB -glGetUniformLocationARB -glUniform1iARB -glUniform1fARB -glUniform4fARB -glUniformMatrix4fvARB - glGenFramebuffersEXT glGenRenderbuffersEXT glBindRenderbufferEXT @@ -136,39 +119,6 @@ typedef ptrdiff_t GLsizeiptr; #define GL_DEPTH_ATTACHMENT_EXT 0x8D00 #endif -#ifndef GL_ARB_vertex_shader -#define GL_VERTEX_SHADER_ARB 0x8B31 -#endif - -#ifndef GL_ARB_fragment_shader -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#endif - -#ifndef GL_ARB_shader_objects -typedef char GLcharARB; -typedef unsigned int GLhandleARB; -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#endif - -typedef GLhandleARB (APIENTRY *_glCreateShaderObjectARB) (GLenum); -typedef void (APIENTRY *_glShaderSourceARB) (GLhandleARB, GLuint, const GLcharARB**, GLint *); -typedef void (APIENTRY *_glCompileShaderARB) (GLhandleARB); -typedef void (APIENTRY *_glGetObjectParameterivARB) (GLhandleARB, GLenum, int *); -typedef void (APIENTRY *_glDeleteObjectARB) (GLhandleARB); -typedef void (APIENTRY *_glGetInfoLogARB) (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); -typedef GLhandleARB (APIENTRY *_glCreateProgramObjectARB) (); -typedef void (APIENTRY *_glAttachObjectARB) (GLhandleARB, GLhandleARB); -typedef void (APIENTRY *_glDetachObjectARB) (GLhandleARB, GLhandleARB); -typedef void (APIENTRY *_glLinkProgramARB) (GLhandleARB); -typedef void (APIENTRY *_glUseProgramObjectARB) (GLhandleARB); -typedef GLint (APIENTRY *_glGetUniformLocationARB) (GLhandleARB, const GLcharARB *); -typedef void (APIENTRY *_glUniform1iARB) (GLint, GLint); -typedef void (APIENTRY *_glUniform1fARB) (GLint, GLfloat); -typedef void (APIENTRY *_glUniform4fARB) (GLint, GLfloat, GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *_glUniformMatrix4fvARB) (GLint, GLuint, GLboolean, const GLfloat *); - typedef void (APIENTRY *_glGenFramebuffersEXT) (GLsizei, GLuint *); typedef void (APIENTRY *_glGenRenderbuffersEXT) (GLsizei, GLuint *); typedef void (APIENTRY *_glBindRenderbufferEXT) (GLenum, GLuint); @@ -194,27 +144,9 @@ struct GLExtensionFunctions { bool resolve(const QGLContext *context); - bool glslSupported(); bool fboSupported(); bool openGL15Supported(); // the rest: multi-texture, 3D-texture, vertex buffer objects - _glCreateShaderObjectARB CreateShaderObjectARB; - _glShaderSourceARB ShaderSourceARB; - _glCompileShaderARB CompileShaderARB; - _glGetObjectParameterivARB GetObjectParameterivARB; - _glDeleteObjectARB DeleteObjectARB; - _glGetInfoLogARB GetInfoLogARB; - _glCreateProgramObjectARB CreateProgramObjectARB; - _glAttachObjectARB AttachObjectARB; - _glDetachObjectARB DetachObjectARB; - _glLinkProgramARB LinkProgramARB; - _glUseProgramObjectARB UseProgramObjectARB; - _glGetUniformLocationARB GetUniformLocationARB; - _glUniform1iARB Uniform1iARB; - _glUniform1fARB Uniform1fARB; - _glUniform4fARB Uniform4fARB; - _glUniformMatrix4fvARB UniformMatrix4fvARB; - _glGenFramebuffersEXT GenFramebuffersEXT; _glGenRenderbuffersEXT GenRenderbuffersEXT; _glBindRenderbufferEXT BindRenderbufferEXT; @@ -243,23 +175,6 @@ inline GLExtensionFunctions &getGLExtensionFunctions() return funcs; } -#define glCreateShaderObjectARB getGLExtensionFunctions().CreateShaderObjectARB -#define glShaderSourceARB getGLExtensionFunctions().ShaderSourceARB -#define glCompileShaderARB getGLExtensionFunctions().CompileShaderARB -#define glGetObjectParameterivARB getGLExtensionFunctions().GetObjectParameterivARB -#define glDeleteObjectARB getGLExtensionFunctions().DeleteObjectARB -#define glGetInfoLogARB getGLExtensionFunctions().GetInfoLogARB -#define glCreateProgramObjectARB getGLExtensionFunctions().CreateProgramObjectARB -#define glAttachObjectARB getGLExtensionFunctions().AttachObjectARB -#define glDetachObjectARB getGLExtensionFunctions().DetachObjectARB -#define glLinkProgramARB getGLExtensionFunctions().LinkProgramARB -#define glUseProgramObjectARB getGLExtensionFunctions().UseProgramObjectARB -#define glGetUniformLocationARB getGLExtensionFunctions().GetUniformLocationARB -#define glUniform1iARB getGLExtensionFunctions().Uniform1iARB -#define glUniform1fARB getGLExtensionFunctions().Uniform1fARB -#define glUniform4fARB getGLExtensionFunctions().Uniform4fARB -#define glUniformMatrix4fvARB getGLExtensionFunctions().UniformMatrix4fvARB - #define glGenFramebuffersEXT getGLExtensionFunctions().GenFramebuffersEXT #define glGenRenderbuffersEXT getGLExtensionFunctions().GenRenderbuffersEXT #define glBindRenderbufferEXT getGLExtensionFunctions().BindRenderbufferEXT diff --git a/demos/boxes/glshaders.cpp b/demos/boxes/glshaders.cpp deleted file mode 100644 index b6999a8..0000000 --- a/demos/boxes/glshaders.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "glshaders.h" - -#define GLSHADERS_ASSERT_OPENGL(prefix, assertion, returnStatement) \ -if (m_failed || !(assertion)) { \ - if (!m_failed) qCritical(prefix ": The necessary OpenGL functions are not available."); \ - m_failed = true; \ - returnStatement; \ -} - - -GLShader::GLShader(const char *data, int size, GLenum shaderType) -: m_compileError(false), m_failed(false) -{ - GLSHADERS_ASSERT_OPENGL("GLShader::GLShader", - glCreateShaderObjectARB && glShaderSourceARB && glCompileShaderARB && glGetObjectParameterivARB, return) - - m_shader = glCreateShaderObjectARB(shaderType); - - GLint glSize = size; - glShaderSourceARB(m_shader, 1, &data, &glSize); - glCompileShaderARB(m_shader); - int status; - glGetObjectParameterivARB(m_shader, GL_OBJECT_COMPILE_STATUS_ARB, &status); - m_compileError = (status != 1); -} - -GLShader::GLShader(const QString& fileName, GLenum shaderType) - : m_compileError(false), m_failed(false) -{ - GLSHADERS_ASSERT_OPENGL("GLShader::GLShader", - glCreateShaderObjectARB && glShaderSourceARB && glCompileShaderARB && glGetObjectParameterivARB, return) - - m_shader = glCreateShaderObjectARB(shaderType); - - QFile file(fileName); - if (file.open(QIODevice::ReadOnly)) { - QByteArray bytes = file.readAll(); - GLint size = file.size(); - const char *p = bytes.data(); - file.close(); - glShaderSourceARB(m_shader, 1, &p, &size); - glCompileShaderARB(m_shader); - int status; - glGetObjectParameterivARB(m_shader, GL_OBJECT_COMPILE_STATUS_ARB, &status); - m_compileError = (status != 1); - } else { - m_compileError = true; - } -} - -GLShader::~GLShader() -{ - GLSHADERS_ASSERT_OPENGL("GLShader::~GLShader", glDeleteObjectARB, return) - - glDeleteObjectARB(m_shader); -} - -QString GLShader::log() -{ - GLSHADERS_ASSERT_OPENGL("GLShader::log", glGetObjectParameterivARB - && glGetInfoLogARB, return QLatin1String("GLSL not supported.")) - - int length; - glGetObjectParameterivARB(m_shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); - char *log = new char[length + 1]; - GLsizei glLength = length; - glGetInfoLogARB(m_shader, glLength, &glLength, log); - log[glLength] = '\0'; - QString result(log); - delete log; - return result; -} - -GLVertexShader::GLVertexShader(const char *data, int size) : GLShader(data, size, GL_VERTEX_SHADER_ARB) -{ -} - -GLVertexShader::GLVertexShader(const QString& fileName) : GLShader(fileName, GL_VERTEX_SHADER_ARB) -{ -} - -GLFragmentShader::GLFragmentShader(const char *data, int size) : GLShader(data, size, GL_FRAGMENT_SHADER_ARB) -{ -} - -GLFragmentShader::GLFragmentShader(const QString& fileName) : GLShader(fileName, GL_FRAGMENT_SHADER_ARB) -{ -} - -GLProgram::GLProgram() : m_linked(false), m_linkError(false), m_failed(false) -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::GLProgram", glCreateProgramObjectARB, return) - - m_program = glCreateProgramObjectARB(); -} - -GLProgram::~GLProgram() -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::~GLProgram", glDeleteObjectARB, return) - - glDeleteObjectARB(m_program); -} - -void GLProgram::attach(const GLShader &shader) -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::attach", glAttachObjectARB, return) - - glAttachObjectARB(m_program, shader.m_shader); - m_linked = m_linkError = false; -} - -void GLProgram::detach(const GLShader &shader) -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::detach", glDetachObjectARB, return) - - glDetachObjectARB(m_program, shader.m_shader); - m_linked = m_linkError = false; -} - -bool GLProgram::failed() -{ - if (m_failed || m_linkError) - return true; - - if (m_linked) - return false; - - GLSHADERS_ASSERT_OPENGL("GLProgram::failed", glLinkProgramARB && glGetObjectParameterivARB, return true) - - glLinkProgramARB(m_program); - int status; - glGetObjectParameterivARB(m_program, GL_OBJECT_LINK_STATUS_ARB, &status); - m_linkError = !(m_linked = (status == 1)); - return m_linkError; -} - -QString GLProgram::log() -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::log", glGetObjectParameterivARB && glGetInfoLogARB, - return QLatin1String("Failed.")) - - int length; - glGetObjectParameterivARB(m_program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); - char *log = new char[length + 1]; - GLsizei glLength = length; - glGetInfoLogARB(m_program, glLength, &glLength, log); - log[glLength] = '\0'; - QString result(log); - delete log; - return result; -} - -void GLProgram::bind() -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::bind", glUseProgramObjectARB, return) - - if (!failed()) - glUseProgramObjectARB(m_program); -} - -void GLProgram::unbind() -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::bind", glUseProgramObjectARB, return) - - glUseProgramObjectARB(0); -} - -bool GLProgram::hasParameter(const QString& name) -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::hasParameter", glGetUniformLocationARB, return false) - - if (!failed()) { - QByteArray asciiName = name.toAscii(); - return -1 != glGetUniformLocationARB(m_program, asciiName.data()); - } - return false; -} - -void GLProgram::setInt(const QString& name, int value) -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::setInt", glGetUniformLocationARB && glUniform1iARB, return) - - if (!failed()) { - QByteArray asciiName = name.toAscii(); - int loc = glGetUniformLocationARB(m_program, asciiName.data()); - glUniform1iARB(loc, value); - } -} - -void GLProgram::setFloat(const QString& name, float value) -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::setFloat", glGetUniformLocationARB && glUniform1fARB, return) - - if (!failed()) { - QByteArray asciiName = name.toAscii(); - int loc = glGetUniformLocationARB(m_program, asciiName.data()); - glUniform1fARB(loc, value); - } -} - -void GLProgram::setColor(const QString& name, QRgb value) -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::setColor", glGetUniformLocationARB && glUniform4fARB, return) - - //qDebug() << "Setting color" << name; - if (!failed()) { - QByteArray asciiName = name.toAscii(); - int loc = glGetUniformLocationARB(m_program, asciiName.data()); - //qDebug() << "Location of" << name << "is" << loc; - QColor color(value); - glUniform4fARB(loc, color.redF(), color.greenF(), color.blueF(), color.alphaF()); - } -} - -void GLProgram::setMatrix(const QString& name, const gfx::Matrix4x4f &mat) -{ - GLSHADERS_ASSERT_OPENGL("GLProgram::setMatrix", glGetUniformLocationARB && glUniformMatrix4fvARB, return) - - if (!failed()) { - QByteArray asciiName = name.toAscii(); - int loc = glGetUniformLocationARB(m_program, asciiName.data()); - //qDebug() << "Location of" << name << "is" << loc; - glUniformMatrix4fvARB(loc, 1, GL_FALSE, mat.bits()); - } -} \ No newline at end of file diff --git a/demos/boxes/glshaders.h b/demos/boxes/glshaders.h deleted file mode 100644 index 2b6209a..0000000 --- a/demos/boxes/glshaders.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GLSHADERS_H -#define GLSHADERS_H - -//#include -#include "glextensions.h" - -#include -#include - -#include "vector.h" - -class GLShader -{ -public: - friend class GLProgram; - virtual ~GLShader(); - bool failed() const {return m_failed;} - QString log(); -protected: - GLShader(const char *data, int size, GLenum shaderType); - GLShader(const QString& fileName, GLenum shaderType); - - GLhandleARB m_shader; - bool m_compileError; - bool m_failed; -}; - -class GLVertexShader : public GLShader -{ -public: - GLVertexShader(const char *data, int size); - GLVertexShader(const QString& fileName); -}; - -class GLFragmentShader : public GLShader -{ -public: - GLFragmentShader(const char *data, int size); - GLFragmentShader(const QString& fileName); -}; - -class GLProgram -{ -public: - GLProgram(); - ~GLProgram(); - void attach(const GLShader &shader); - void detach(const GLShader &shader); - void bind(); - void unbind(); - bool failed(); - QString log(); - bool hasParameter(const QString& name); - // use program before setting values - void setInt(const QString& name, int value); - void setFloat(const QString& name, float value); - void setColor(const QString& name, QRgb value); - void setMatrix(const QString& name, const gfx::Matrix4x4f &mat); - // TODO: add a bunch of set-functions for different types. -private: - GLhandleARB m_program; - bool m_linked; - bool m_linkError; - bool m_failed; -}; - -#endif diff --git a/demos/boxes/scene.cpp b/demos/boxes/scene.cpp index 1040e17..e5aab75 100644 --- a/demos/boxes/scene.cpp +++ b/demos/boxes/scene.cpp @@ -531,11 +531,11 @@ Scene::~Scene() if (texture) delete texture; if (m_mainCubemap) delete m_mainCubemap; - foreach (GLProgram *program, m_programs) + foreach (QGLShaderProgram *program, m_programs) if (program) delete program; if (m_vertexShader) delete m_vertexShader; - foreach (GLFragmentShader *shader, m_fragmentShaders) + foreach (QGLShader *shader, m_fragmentShaders) if (shader) delete shader; foreach (GLRenderTargetCube *rt, m_cubemaps) if (rt) delete rt; @@ -549,16 +549,18 @@ void Scene::initGL() { m_box = new GLRoundedBox(0.25f, 1.0f, 10); - m_vertexShader = new GLVertexShader(":/res/boxes/basic.vsh"); + m_vertexShader = new QGLShader(":/res/boxes/basic.vsh", QGLShader::VertexShader); QStringList list; list << ":/res/boxes/cubemap_posx.jpg" << ":/res/boxes/cubemap_negx.jpg" << ":/res/boxes/cubemap_posy.jpg" << ":/res/boxes/cubemap_negy.jpg" << ":/res/boxes/cubemap_posz.jpg" << ":/res/boxes/cubemap_negz.jpg"; m_environment = new GLTextureCube(list, qMin(1024, m_maxTextureSize)); - m_environmentShader = new GLFragmentShader(environmentShaderText, strlen(environmentShaderText)); - m_environmentProgram = new GLProgram; - m_environmentProgram->attach(*m_vertexShader); - m_environmentProgram->attach(*m_environmentShader); + m_environmentShader = new QGLShader(QGLShader::FragmentShader); + m_environmentShader->setSourceCode(environmentShaderText); + m_environmentProgram = new QGLShaderProgram; + m_environmentProgram->addShader(m_vertexShader); + m_environmentProgram->addShader(m_environmentShader); + m_environmentProgram->link(); const int NOISE_SIZE = 128; // for a different size, B and BM in fbm.c must also be changed m_noise = new GLTexture3D(NOISE_SIZE, NOISE_SIZE, NOISE_SIZE); @@ -610,19 +612,19 @@ void Scene::initGL() filter = QStringList("*.fsh"); files = QDir(":/res/boxes/").entryInfoList(filter, QDir::Files | QDir::Readable); foreach (QFileInfo file, files) { - GLProgram *program = new GLProgram; - GLFragmentShader* shader = new GLFragmentShader(file.absoluteFilePath()); + QGLShaderProgram *program = new QGLShaderProgram; + QGLShader* shader = new QGLShader(file.absoluteFilePath(), QGLShader::FragmentShader); // The program does not take ownership over the shaders, so store them in a vector so they can be deleted afterwards. - program->attach(*m_vertexShader); - program->attach(*shader); - if (program->failed()) { + program->addShader(m_vertexShader); + program->addShader(shader); + if (!program->link()) { qWarning("Failed to compile and link shader program"); qWarning("Vertex shader log:"); - qWarning() << m_vertexShader->log(); + qWarning() << m_vertexShader->errors(); qWarning() << "Fragment shader log ( file =" << file.absoluteFilePath() << "):"; - qWarning() << shader->log(); + qWarning() << shader->errors(); qWarning("Shader program log:"); - qWarning() << program->log(); + qWarning() << program->errors(); delete shader; delete program; @@ -633,13 +635,13 @@ void Scene::initGL() m_programs << program; m_renderOptions->addShader(file.baseName()); - program->bind(); - m_cubemaps << (program->hasParameter("env") ? new GLRenderTargetCube(qMin(256, m_maxTextureSize)) : 0); - program->unbind(); + program->enable(); + m_cubemaps << ((program->uniformLocation("env") != -1) ? new GLRenderTargetCube(qMin(256, m_maxTextureSize)) : 0); + program->disable(); } if (m_programs.size() == 0) - m_programs << new GLProgram; + m_programs << new QGLShaderProgram; m_renderOptions->emitParameterChanged(); } @@ -674,12 +676,12 @@ void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) // Don't render the environment if the environment texture can't be set for the correct sampler. if (glActiveTexture) { m_environment->bind(); - m_environmentProgram->bind(); - m_environmentProgram->setInt("tex", 0); - m_environmentProgram->setInt("env", 1); - m_environmentProgram->setInt("noise", 2); + m_environmentProgram->enable(); + m_environmentProgram->setUniformValue("tex", 0); + m_environmentProgram->setUniformValue("env", 1); + m_environmentProgram->setUniformValue("noise", 2); m_box->draw(); - m_environmentProgram->unbind(); + m_environmentProgram->disable(); m_environment->unbind(); } @@ -707,14 +709,18 @@ void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) else m_environment->bind(); } - m_programs[i]->bind(); - m_programs[i]->setInt("tex", 0); - m_programs[i]->setInt("env", 1); - m_programs[i]->setInt("noise", 2); - m_programs[i]->setMatrix("view", view); - m_programs[i]->setMatrix("invView", invView); + m_programs[i]->enable(); + m_programs[i]->setUniformValue("tex", 0); + m_programs[i]->setUniformValue("env", 1); + m_programs[i]->setUniformValue("noise", 2); + QMatrix4x4 mview; + QMatrix4x4 minvview; + memcpy(mview.data(), view.bits(), sizeof(float) * 16); + memcpy(minvview.data(), invView.bits(), sizeof(float) * 16); + m_programs[i]->setUniformValue("view", mview); + m_programs[i]->setUniformValue("invView", minvview); m_box->draw(); - m_programs[i]->unbind(); + m_programs[i]->disable(); if (glActiveTexture) { if (m_dynamicCubemap && m_cubemaps[i]) @@ -737,14 +743,18 @@ void Scene::renderBoxes(const gfx::Matrix4x4f &view, int excludeBox) m_environment->bind(); } - m_programs[m_currentShader]->bind(); - m_programs[m_currentShader]->setInt("tex", 0); - m_programs[m_currentShader]->setInt("env", 1); - m_programs[m_currentShader]->setInt("noise", 2); - m_programs[m_currentShader]->setMatrix("view", view); - m_programs[m_currentShader]->setMatrix("invView", invView); + m_programs[m_currentShader]->enable(); + m_programs[m_currentShader]->setUniformValue("tex", 0); + m_programs[m_currentShader]->setUniformValue("env", 1); + m_programs[m_currentShader]->setUniformValue("noise", 2); + QMatrix4x4 mview; + QMatrix4x4 minvview; + memcpy(mview.data(), view.bits(), sizeof(float) * 16); + memcpy(minvview.data(), invView.bits(), sizeof(float) * 16); + m_programs[m_currentShader]->setUniformValue("view", mview); + m_programs[m_currentShader]->setUniformValue("invView", minvview); m_box->draw(); - m_programs[m_currentShader]->unbind(); + m_programs[m_currentShader]->disable(); if (glActiveTexture) { if (m_dynamicCubemap) @@ -1021,20 +1031,20 @@ void Scene::toggleDynamicCubemap(int state) void Scene::setColorParameter(const QString &name, QRgb color) { // set the color in all programs - foreach (GLProgram *program, m_programs) { - program->bind(); - program->setColor(name, color); - program->unbind(); + foreach (QGLShaderProgram *program, m_programs) { + program->enable(); + program->setUniformValue(program->uniformLocation(name), QColor(color)); + program->disable(); } } void Scene::setFloatParameter(const QString &name, float value) { // set the color in all programs - foreach (GLProgram *program, m_programs) { - program->bind(); - program->setFloat(name, value); - program->unbind(); + foreach (QGLShaderProgram *program, m_programs) { + program->enable(); + program->setUniformValue(program->uniformLocation(name), value); + program->disable(); } } diff --git a/demos/boxes/scene.h b/demos/boxes/scene.h index 2db9317..c056739 100644 --- a/demos/boxes/scene.h +++ b/demos/boxes/scene.h @@ -53,7 +53,6 @@ #include "vector.h" #include "trackball.h" #include "glbuffers.h" -#include "glshaders.h" #include "qtbox.h" #define PI 3.14159265358979 @@ -231,11 +230,11 @@ private: GLTexture3D *m_noise; GLRenderTargetCube *m_mainCubemap; QVector m_cubemaps; - QVector m_programs; - GLVertexShader *m_vertexShader; - QVector m_fragmentShaders; - GLFragmentShader *m_environmentShader; - GLProgram *m_environmentProgram; + QVector m_programs; + QGLShader *m_vertexShader; + QVector m_fragmentShaders; + QGLShader *m_environmentShader; + QGLShaderProgram *m_environmentProgram; }; diff --git a/examples/opengl/hellogl_es2/glwidget.cpp b/examples/opengl/hellogl_es2/glwidget.cpp index 213c5b2..ee50670 100644 --- a/examples/opengl/hellogl_es2/glwidget.cpp +++ b/examples/opengl/hellogl_es2/glwidget.cpp @@ -48,124 +48,10 @@ const int bubbleNum = 8; -inline void CrossProduct(qreal &xOut, qreal &yOut, qreal &zOut, qreal x1, qreal y1, qreal z1, qreal x2, qreal y2, qreal z2) -{ - xOut = y1 * z2 - z1 * y2; - yOut = z1 * x2 - x1 * z2; - zOut = x1 * y2 - y1 * x2; -} - -inline void Normalize(qreal &x, qreal &y, qreal &z) -{ - qreal l = sqrt(x*x + y*y + z*z); - x = x / l; - y = y / l; - z = z / l; -} - -inline void IdentityMatrix(GLfloat *m) -{ - m[0 * 4 + 0] = 1.0f; - m[1 * 4 + 0] = 0.0f; - m[2 * 4 + 0] = 0.0f; - m[3 * 4 + 0] = 0.0f; - m[0 * 4 + 1] = 0.0f; - m[1 * 4 + 1] = 1.0f; - m[2 * 4 + 1] = 0.0f; - m[3 * 4 + 1] = 0.0f; - m[0 * 4 + 2] = 0.0f; - m[1 * 4 + 2] = 0.0f; - m[2 * 4 + 2] = 1.0f; - m[3 * 4 + 2] = 0.0f; - m[0 * 4 + 3] = 0.0f; - m[1 * 4 + 3] = 0.0f; - m[2 * 4 + 3] = 0.0f; - m[3 * 4 + 3] = 1.0f; -} - -// Adjust a 4x4 matrix to apply a scale. -inline void ScaleMatrix(GLfloat *m, GLfloat scalex, GLfloat scaley, GLfloat scalez) -{ - m[0 * 4 + 0] *= scalex; - m[0 * 4 + 1] *= scalex; - m[0 * 4 + 2] *= scalex; - m[0 * 4 + 3] *= scalex; - m[1 * 4 + 0] *= scaley; - m[1 * 4 + 1] *= scaley; - m[1 * 4 + 2] *= scaley; - m[1 * 4 + 3] *= scaley; - m[2 * 4 + 0] *= scalez; - m[2 * 4 + 1] *= scalez; - m[2 * 4 + 2] *= scalez; - m[2 * 4 + 3] *= scalez; -} - -// Adjust a 4x4 matrix to apply a translation. -inline void TranslateMatrix(GLfloat *m, GLfloat translatex, GLfloat translatey, GLfloat translatez) -{ - m[3 * 4 + 0] += m[0 * 4 + 0] * translatex + m[1 * 4 + 0] * translatey + m[2 * 4 + 0] * translatez; - m[3 * 4 + 1] += m[0 * 4 + 1] * translatex + m[1 * 4 + 1] * translatey + m[2 * 4 + 1] * translatez; - m[3 * 4 + 2] += m[0 * 4 + 2] * translatex + m[1 * 4 + 2] * translatey + m[2 * 4 + 2] * translatez; - m[3 * 4 + 3] += m[0 * 4 + 3] * translatex + m[1 * 4 + 3] * translatey + m[2 * 4 + 3] * translatez; -} - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -// Adjust a 4x4 matrix to apply a rotation. -inline void RotateMatrix(GLfloat *m, GLfloat angle, GLfloat vx, GLfloat vy, GLfloat vz) -{ - GLfloat len = sqrt(vx * vx + vy * vy + vz * vz); - if (len != 0) { - vx /= len; - vy /= len; - vz /= len; - } - - GLfloat c, s, ic; - c = cos(angle * M_PI / 180.0); - s = sin(angle * M_PI / 180.0); - ic = 1.0f - c; - - GLfloat rot[16]; - rot[0 * 4 + 0] = vx * vx * ic + c; - rot[1 * 4 + 0] = vx * vy * ic - vz * s; - rot[2 * 4 + 0] = vx * vz * ic + vy * s; - rot[3 * 4 + 0] = 0.0f; - rot[0 * 4 + 1] = vy * vx * ic + vz * s; - rot[1 * 4 + 1] = vy * vy * ic + c; - rot[2 * 4 + 1] = vy * vz * ic - vx * s; - rot[3 * 4 + 1] = 0.0f; - rot[0 * 4 + 2] = vx * vz * ic - vy * s; - rot[1 * 4 + 2] = vy * vz * ic + vx * s; - rot[2 * 4 + 2] = vz * vz * ic + c; - rot[3 * 4 + 2] = 0.0f; - rot[0 * 4 + 3] = 0.0f; - rot[1 * 4 + 3] = 0.0f; - rot[2 * 4 + 3] = 0.0f; - rot[3 * 4 + 3] = 1.0f; - - GLfloat temp[16]; - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - temp[j * 4 + i] = 0.0f; - for (int k = 0; k < 4; ++k) { - temp[j * 4 + i] += m[k * 4 + i] * rot[j * 4 + k]; - } - } - } - - qMemCopy(m, temp, sizeof(temp)); -} - GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent) { qtLogo = true; - createdVertices = 0; - createdNormals = 0; - m_vertexNumber = 0; frames = 0; setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); @@ -178,10 +64,6 @@ GLWidget::GLWidget(QWidget *parent) GLWidget::~GLWidget() { - if (createdVertices) - delete[] createdVertices; - if (createdNormals) - delete[] createdNormals; } void GLWidget::setScaling(int scale) { @@ -210,13 +92,11 @@ void GLWidget::showBubbles(bool bubbles) void GLWidget::paintQtLogo() { glDisable(GL_TEXTURE_2D); - glVertexAttribPointer(vertexAttr1, 3, GL_FLOAT, GL_FALSE, 0, createdVertices); - glEnableVertexAttribArray(vertexAttr1); - glVertexAttribPointer(normalAttr1, 3, GL_FLOAT, GL_FALSE, 0, createdNormals); - glEnableVertexAttribArray(normalAttr1); - glDrawArrays(GL_TRIANGLES, 0, m_vertexNumber / 3); - glDisableVertexAttribArray(normalAttr1); - glDisableVertexAttribArray(vertexAttr1); + program1.setAttributeArray(vertexAttr1, vertices.constData()); + program1.setAttributeArray(normalAttr1, normals.constData()); + glDrawArrays(GL_TRIANGLES, 0, vertices.size()); + program1.disableAttributeArray(normalAttr1); + program1.disableAttributeArray(vertexAttr1); } void GLWidget::paintTexturedCube() @@ -239,8 +119,7 @@ void GLWidget::paintTexturedCube() -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5 }; - glVertexAttribPointer(vertexAttr2, 3, GL_FLOAT, GL_FALSE, 0, afVertices); - glEnableVertexAttribArray(vertexAttr2); + program2.setAttributeArray(vertexAttr2, afVertices, 3); GLfloat afTexCoord[] = { 0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f, @@ -258,8 +137,7 @@ void GLWidget::paintTexturedCube() 1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f }; - glVertexAttribPointer(texCoordAttr2, 2, GL_FLOAT, GL_FALSE, 0, afTexCoord); - glEnableVertexAttribArray(texCoordAttr2); + program2.setAttributeArray(texCoordAttr2, afTexCoord, 2); GLfloat afNormals[] = { @@ -278,50 +156,15 @@ void GLWidget::paintTexturedCube() 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0 }; - glVertexAttribPointer(normalAttr2, 3, GL_FLOAT, GL_FALSE, 0, afNormals); - glEnableVertexAttribArray(normalAttr2); + program2.setAttributeArray(normalAttr2, afNormals, 3); - glUniform1i(textureUniform2, 0); // use texture unit 0 + program2.setUniformValue(textureUniform2, 0); // use texture unit 0 glDrawArrays(GL_TRIANGLES, 0, 36); - glDisableVertexAttribArray(vertexAttr2); - glDisableVertexAttribArray(normalAttr2); - glDisableVertexAttribArray(texCoordAttr2); -} - -static void reportCompileErrors(GLuint shader, const char *src) -{ - GLint value = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &value); - bool compiled = (value != 0); - value = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value); - if (!compiled && value > 1) { - char *log = new char [value]; - GLint len; - glGetShaderInfoLog(shader, value, &len, log); - qWarning("%s\n", log); - qWarning("when compiling:\n%s\n", src); - delete [] log; - } -} - -static void reportLinkErrors(GLuint program, const char *vsrc, const char *fsrc) -{ - GLint value = 0; - glGetProgramiv(program, GL_LINK_STATUS, &value); - bool linked = (value != 0); - value = 0; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value); - if (!linked && value > 1) { - char *log = new char [value]; - GLint len; - glGetProgramInfoLog(program, value, &len, log); - qWarning("%s\n", log); - qWarning("when linking:\n%s\nwith:\n%s\n", vsrc, fsrc); - delete [] log; - } + program2.disableAttributeArray(vertexAttr2); + program2.disableAttributeArray(normalAttr2); + program2.disableAttributeArray(texCoordAttr2); } void GLWidget::initializeGL () @@ -332,8 +175,8 @@ void GLWidget::initializeGL () glGenTextures(1, &m_uiTexture); m_uiTexture = bindTexture(QImage(":/qt.png")); - GLuint vshader1 = glCreateShader(GL_VERTEX_SHADER); - const char *vsrc1[1] = { + QGLShader *vshader1 = new QGLShader(QGLShader::VertexShader, this); + const char *vsrc1 = "attribute highp vec4 vertex;\n" "attribute mediump vec3 normal;\n" "uniform mediump mat4 matrix;\n" @@ -346,36 +189,28 @@ void GLWidget::initializeGL () " color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);\n" " color = clamp(color, 0.0, 1.0);\n" " gl_Position = matrix * vertex;\n" - "}\n" - }; - glShaderSource(vshader1, 1, vsrc1, 0); - glCompileShader(vshader1); - reportCompileErrors(vshader1, vsrc1[0]); + "}\n"; + vshader1->setSourceCode(vsrc1); - GLuint fshader1 = glCreateShader(GL_FRAGMENT_SHADER); - const char *fsrc1[1] = { + QGLShader *fshader1 = new QGLShader(QGLShader::FragmentShader, this); + const char *fsrc1 = "varying mediump vec4 color;\n" "void main(void)\n" "{\n" " gl_FragColor = color;\n" - "}\n" - }; - glShaderSource(fshader1, 1, fsrc1, 0); - glCompileShader(fshader1); - reportCompileErrors(fshader1, fsrc1[0]); - - program1 = glCreateProgram(); - glAttachShader(program1, vshader1); - glAttachShader(program1, fshader1); - glLinkProgram(program1); - reportLinkErrors(program1, vsrc1[0], fsrc1[0]); - - vertexAttr1 = glGetAttribLocation(program1, "vertex"); - normalAttr1 = glGetAttribLocation(program1, "normal"); - matrixUniform1 = glGetUniformLocation(program1, "matrix"); - - GLuint vshader2 = glCreateShader(GL_VERTEX_SHADER); - const char *vsrc2[1] = { + "}\n"; + fshader1->setSourceCode(fsrc1); + + program1.addShader(vshader1); + program1.addShader(fshader1); + program1.link(); + + vertexAttr1 = program1.attributeLocation("vertex"); + normalAttr1 = program1.attributeLocation("normal"); + matrixUniform1 = program1.uniformLocation("matrix"); + + QGLShader *vshader2 = new QGLShader(QGLShader::VertexShader); + const char *vsrc2 = "attribute highp vec4 vertex;\n" "attribute highp vec4 texCoord;\n" "attribute mediump vec3 normal;\n" @@ -388,14 +223,11 @@ void GLWidget::initializeGL () " angle = max(dot(normal, toLight), 0.0);\n" " gl_Position = matrix * vertex;\n" " texc = texCoord;\n" - "}\n" - }; - glShaderSource(vshader2, 1, vsrc2, 0); - glCompileShader(vshader2); - reportCompileErrors(vshader2, vsrc2[0]); + "}\n"; + vshader2->setSourceCode(vsrc2); - GLuint fshader2 = glCreateShader(GL_FRAGMENT_SHADER); - const char *fsrc2[1] = { + QGLShader *fshader2 = new QGLShader(QGLShader::FragmentShader); + const char *fsrc2 = "varying highp vec4 texc;\n" "uniform sampler2D tex;\n" "varying mediump float angle;\n" @@ -404,23 +236,18 @@ void GLWidget::initializeGL () " highp vec3 color = texture2D(tex, texc.st).rgb;\n" " color = color * 0.2 + color * 0.8 * angle;\n" " gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0);\n" - "}\n" - }; - glShaderSource(fshader2, 1, fsrc2, 0); - glCompileShader(fshader2); - reportCompileErrors(fshader2, fsrc2[0]); - - program2 = glCreateProgram(); - glAttachShader(program2, vshader2); - glAttachShader(program2, fshader2); - glLinkProgram(program2); - reportLinkErrors(program2, vsrc2[0], fsrc2[0]); - - vertexAttr2 = glGetAttribLocation(program2, "vertex"); - normalAttr2 = glGetAttribLocation(program2, "normal"); - texCoordAttr2 = glGetAttribLocation(program2, "texCoord"); - matrixUniform2 = glGetUniformLocation(program2, "matrix"); - textureUniform2 = glGetUniformLocation(program2, "tex"); + "}\n"; + fshader2->setSourceCode(fsrc2); + + program2.addShader(vshader2); + program2.addShader(fshader2); + program2.link(); + + vertexAttr2 = program2.attributeLocation("vertex"); + normalAttr2 = program2.attributeLocation("normal"); + texCoordAttr2 = program2.attributeLocation("texCoord"); + matrixUniform2 = program2.uniformLocation("matrix"); + textureUniform2 = program2.uniformLocation("tex"); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); @@ -450,24 +277,23 @@ void GLWidget::paintGL() glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); - GLfloat modelview[16]; - IdentityMatrix(modelview); - RotateMatrix(modelview, m_fAngle, 0.0, 1.0, 0.0); - RotateMatrix(modelview, m_fAngle, 1.0, 0.0, 0.0); - RotateMatrix(modelview, m_fAngle, 0.0, 0.0, 1.0); - ScaleMatrix(modelview, m_fScale, m_fScale, m_fScale); - TranslateMatrix(modelview, 0, -0.2, 0); + QMatrix4x4 modelview; + modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f); + modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f); + modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f); + modelview.scale(m_fScale); + modelview.translate(0.0f, -0.2f, 0.0f); if (qtLogo) { - glUseProgram(program1); - glUniformMatrix4fv(matrixUniform1, 1, GL_FALSE, modelview); + program1.enable(); + program1.setUniformValue(matrixUniform1, modelview); paintQtLogo(); - glUseProgram(0); + program1.disable(); } else { - glUseProgram(program2); - glUniformMatrix4fv(matrixUniform2, 1, GL_FALSE, modelview); + program2.enable(); + program1.setUniformValue(matrixUniform2, modelview); paintTexturedCube(); - glUseProgram(0); + program2.disable(); } glDisable(GL_DEPTH_TEST); @@ -563,80 +389,69 @@ void GLWidget::createGeometry() extrude(x8, y8, x5, y5); } - m_vertexNumber = vertices.size(); - createdVertices = new GLfloat[m_vertexNumber]; - createdNormals = new GLfloat[m_vertexNumber]; - for (int i = 0;i < m_vertexNumber;i++) { - createdVertices[i] = vertices.at(i) * 2; - createdNormals[i] = normals.at(i); - } - vertices.clear(); - normals.clear(); + for (int i = 0;i < vertices.size();i++) + vertices[i] *= 2.0f; } void GLWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4) { - qreal nx, ny, nz; + vertices << QVector3D(x1, y1, -0.05f); + vertices << QVector3D(x2, y2, -0.05f); + vertices << QVector3D(x4, y4, -0.05f); - vertices << x1 << y1 << -0.05f; - vertices << x2 << y2 << -0.05f; - vertices << x4 << y4 << -0.05f; + vertices << QVector3D(x3, y3, -0.05f); + vertices << QVector3D(x4, y4, -0.05f); + vertices << QVector3D(x2, y2, -0.05f); - vertices << x3 << y3 << -0.05f; - vertices << x4 << y4 << -0.05f; - vertices << x2 << y2 << -0.05f; + QVector3D n = QVector3D::normal + (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f)); - CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0, x4 - x1, y4 - y1, 0); - Normalize(nx, ny, nz); + normals << n; + normals << n; + normals << n; - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; + normals << n; + normals << n; + normals << n; - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; + vertices << QVector3D(x4, y4, 0.05f); + vertices << QVector3D(x2, y2, 0.05f); + vertices << QVector3D(x1, y1, 0.05f); - vertices << x4 << y4 << 0.05f; - vertices << x2 << y2 << 0.05f; - vertices << x1 << y1 << 0.05f; + vertices << QVector3D(x2, y2, 0.05f); + vertices << QVector3D(x4, y4, 0.05f); + vertices << QVector3D(x3, y3, 0.05f); - vertices << x2 << y2 << 0.05f; - vertices << x4 << y4 << 0.05f; - vertices << x3 << y3 << 0.05f; + n = QVector3D::normal + (QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f)); - CrossProduct(nx, ny, nz, x2 - x4, y2 - y4, 0, x1 - x4, y1 - y4, 0); - Normalize(nx, ny, nz); + normals << n; + normals << n; + normals << n; - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; - - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; + normals << n; + normals << n; + normals << n; } void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2) { - qreal nx, ny, nz; - - vertices << x1 << y1 << +0.05f; - vertices << x2 << y2 << +0.05f; - vertices << x1 << y1 << -0.05f; + vertices << QVector3D(x1, y1, +0.05f); + vertices << QVector3D(x2, y2, +0.05f); + vertices << QVector3D(x1, y1, -0.05f); - vertices << x2 << y2 << -0.05f; - vertices << x1 << y1 << -0.05f; - vertices << x2 << y2 << +0.05f; + vertices << QVector3D(x2, y2, -0.05f); + vertices << QVector3D(x1, y1, -0.05f); + vertices << QVector3D(x2, y2, +0.05f); - CrossProduct(nx, ny, nz, x2 - x1, y2 - y1, 0.0f, 0.0f, 0.0f, -0.1f); - Normalize(nx, ny, nz); + QVector3D n = QVector3D::normal + (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f)); - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; + normals << n; + normals << n; + normals << n; - normals << nx << ny << nz; - normals << nx << ny << nz; - normals << nx << ny << nz; + normals << n; + normals << n; + normals << n; } diff --git a/examples/opengl/hellogl_es2/glwidget.h b/examples/opengl/hellogl_es2/glwidget.h index 9a7823a..596e1cc 100644 --- a/examples/opengl/hellogl_es2/glwidget.h +++ b/examples/opengl/hellogl_es2/glwidget.h @@ -43,7 +43,11 @@ #define GLWIDGET_H #include +#include +#include +#include #include +#include class Bubble; class GLWidget : public QGLWidget { @@ -71,24 +75,21 @@ private: void createBubbles(int number); void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4); void extrude(qreal x1, qreal y1, qreal x2, qreal y2); - QList vertices; - QList normals; - GLfloat *createdVertices; - GLfloat *createdNormals; - int m_vertexNumber; + QVector vertices; + QVector normals; bool qtLogo; QList bubbles; int frames; QTime time; - GLuint program1; - GLuint program2; - GLuint vertexAttr1; - GLuint normalAttr1; - GLuint matrixUniform1; - GLuint vertexAttr2; - GLuint normalAttr2; - GLuint texCoordAttr2; - GLuint matrixUniform2; - GLuint textureUniform2; + QGLShaderProgram program1; + QGLShaderProgram program2; + int vertexAttr1; + int normalAttr1; + int matrixUniform1; + int vertexAttr2; + int normalAttr2; + int texCoordAttr2; + int matrixUniform2; + int textureUniform2; }; #endif diff --git a/src/opengl/gl2paintengineex/qglshader_p.h b/src/opengl/gl2paintengineex/qglshader_p.h index 4cbf3f6..64c9a42 100644 --- a/src/opengl/gl2paintengineex/qglshader_p.h +++ b/src/opengl/gl2paintengineex/qglshader_p.h @@ -81,7 +81,8 @@ SAMPLER_2D_SHADOW. #include -#include +#define QGLShader QGLEngineShader +#define QGLShaderProgram QGLEngineShaderProgram typedef struct { GLfloat a; diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index af16312..3b8bfa1 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -25,14 +25,16 @@ HEADERS += qgl.h \ qglcolormap.h \ qglpixelbuffer.h \ qglframebufferobject.h \ - qglpixmapfilter_p.h + qglpixmapfilter_p.h \ + qglshaderprogram.h SOURCES += qgl.cpp \ qglcolormap.cpp \ qglpixelbuffer.cpp \ qglframebufferobject.cpp \ qglextensions.cpp \ - qglpixmapfilter.cpp + qglpixmapfilter.cpp \ + qglshaderprogram.cpp #!contains(QT_CONFIG, opengles2) { # HEADERS += qpaintengine_opengl_p.h diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp index e6ac043..5fda346 100644 --- a/src/opengl/qglextensions.cpp +++ b/src/opengl/qglextensions.cpp @@ -153,55 +153,179 @@ bool qt_resolve_buffer_extensions(QGLContext *ctx) bool qt_resolve_glsl_extensions(QGLContext *ctx) { +#if defined(QT_OPENGL_ES_2) + // The GLSL shader functions are always present in OpenGL/ES 2.0. + // The only exceptions are glGetProgramBinaryOES and glProgramBinaryOES. + if (!QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glslResolved) { + glGetProgramBinaryOES = (_glGetProgramBinaryOES) ctx->getProcAddress(QLatin1String("glGetProgramBinaryOES")); + glProgramBinaryOES = (_glProgramBinaryOES) ctx->getProcAddress(QLatin1String("glProgramBinaryOES")); + QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glslResolved = true; + } + return true; +#else if (glCreateShader) return true; glCreateShader = (_glCreateShader) ctx->getProcAddress(QLatin1String("glCreateShader")); - glShaderSource = (_glShaderSource) ctx->getProcAddress(QLatin1String("glShaderSource")); - glCompileShader = (_glCompileShader) ctx->getProcAddress(QLatin1String("glCompileShader")); - glDeleteShader = (_glDeleteShader) ctx->getProcAddress(QLatin1String("glDeleteShader")); - - glCreateProgram = (_glCreateProgram) ctx->getProcAddress(QLatin1String("glCreateProgram")); - glAttachShader = (_glAttachShader) ctx->getProcAddress(QLatin1String("glAttachShader")); - glDetachShader = (_glDetachShader) ctx->getProcAddress(QLatin1String("glDetachShader")); - glLinkProgram = (_glLinkProgram) ctx->getProcAddress(QLatin1String("glLinkProgram")); - glUseProgram = (_glUseProgram) ctx->getProcAddress(QLatin1String("glUseProgram")); - glDeleteProgram = (_glDeleteProgram) ctx->getProcAddress(QLatin1String("glDeleteProgram")); - - glGetShaderInfoLog = (_glGetShaderInfoLog) ctx->getProcAddress(QLatin1String("glGetShaderInfoLog")); - glGetShaderiv = (_glGetShaderiv) ctx->getProcAddress(QLatin1String("glGetShaderiv")); - glGetProgramiv = (_glGetProgramiv) ctx->getProcAddress(QLatin1String("glGetProgramiv")); - - glGetUniformLocation = (_glGetUniformLocation) ctx->getProcAddress(QLatin1String("glGetUniformLocation")); - glUniform4fv = (_glUniform4fv) ctx->getProcAddress(QLatin1String("glUniform4fv")); - glUniform3fv = (_glUniform3fv) ctx->getProcAddress(QLatin1String("glUniform3fv")); - glUniform2fv = (_glUniform2fv) ctx->getProcAddress(QLatin1String("glUniform2fv")); - glUniform1fv = (_glUniform1fv) ctx->getProcAddress(QLatin1String("glUniform1fv")); - glUniform1i = (_glUniform1i) ctx->getProcAddress(QLatin1String("glUniform1i")); - - glGetActiveAttrib = (_glGetActiveAttrib) ctx->getProcAddress(QLatin1String("glGetActiveAttrib")); - glGetAttribLocation = (_glGetAttribLocation) ctx->getProcAddress(QLatin1String("glGetAttribLocation")); - glGetActiveUniform = (_glGetActiveUniform) ctx->getProcAddress(QLatin1String("glGetActiveUniform")); - glGetProgramInfoLog = (_glGetProgramInfoLog) ctx->getProcAddress(QLatin1String("glGetProgramInfoLog")); - glUniform1f = (_glUniform1f) ctx->getProcAddress(QLatin1String("glUniform1f")); - glUniform2f = (_glUniform2f) ctx->getProcAddress(QLatin1String("glUniform2f")); - glUniform4f = (_glUniform4f) ctx->getProcAddress(QLatin1String("glUniform4f")); - glUniformMatrix2fv = (_glUniformMatrix2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2fv")); - glUniformMatrix3fv = (_glUniformMatrix3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3fv")); - glUniformMatrix4fv = (_glUniformMatrix4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4fv")); - glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArray")); - glDisableVertexAttribArray = (_glDisableVertexAttribArray) ctx->getProcAddress(QLatin1String("glDisableVertexAttribArray")); - glVertexAttribPointer = (_glVertexAttribPointer) ctx->getProcAddress(QLatin1String("glVertexAttribPointer")); - glStencilOpSeparate = (_glStencilOpSeparate) ctx->getProcAddress(QLatin1String("glStencilOpSeparate")); - - return glCreateShader && glShaderSource && glCompileShader && glDeleteProgram && - glCreateProgram && glAttachShader && glDetachShader && glLinkProgram && glUseProgram && - glDeleteProgram && glGetShaderInfoLog && glGetShaderiv && glGetProgramiv && glGetUniformLocation && - glUniform1i && glUniform1fv && glUniform2fv && glUniform3fv && glUniform4fv && - glGetActiveAttrib && glGetAttribLocation && glGetActiveUniform && glGetProgramInfoLog && - glUniform1f && glUniform2f && glUniform4f && - glUniformMatrix2fv && glUniformMatrix3fv && glUniformMatrix4fv && - glEnableVertexAttribArray && glDisableVertexAttribArray && glVertexAttribPointer && glStencilOpSeparate; + if (glCreateShader) { + glShaderSource = (_glShaderSource) ctx->getProcAddress(QLatin1String("glShaderSource")); + glShaderBinary = (_glShaderBinary) ctx->getProcAddress(QLatin1String("glShaderBinary")); + glCompileShader = (_glCompileShader) ctx->getProcAddress(QLatin1String("glCompileShader")); + glDeleteShader = (_glDeleteShader) ctx->getProcAddress(QLatin1String("glDeleteShader")); + glIsShader = (_glIsShader) ctx->getProcAddress(QLatin1String("glIsShader")); + + glCreateProgram = (_glCreateProgram) ctx->getProcAddress(QLatin1String("glCreateProgram")); + glAttachShader = (_glAttachShader) ctx->getProcAddress(QLatin1String("glAttachShader")); + glDetachShader = (_glDetachShader) ctx->getProcAddress(QLatin1String("glDetachShader")); + glLinkProgram = (_glLinkProgram) ctx->getProcAddress(QLatin1String("glLinkProgram")); + glUseProgram = (_glUseProgram) ctx->getProcAddress(QLatin1String("glUseProgram")); + glDeleteProgram = (_glDeleteProgram) ctx->getProcAddress(QLatin1String("glDeleteProgram")); + glIsProgram = (_glIsProgram) ctx->getProcAddress(QLatin1String("glIsProgram")); + + glGetShaderInfoLog = (_glGetShaderInfoLog) ctx->getProcAddress(QLatin1String("glGetShaderInfoLog")); + glGetShaderiv = (_glGetShaderiv) ctx->getProcAddress(QLatin1String("glGetShaderiv")); + glGetShaderSource = (_glGetShaderSource) ctx->getProcAddress(QLatin1String("glGetShaderSource")); + glGetProgramiv = (_glGetProgramiv) ctx->getProcAddress(QLatin1String("glGetProgramiv")); + glGetProgramInfoLog = (_glGetProgramInfoLog) ctx->getProcAddress(QLatin1String("glGetProgramInfoLog")); + + glGetActiveUniform = (_glGetActiveUniform) ctx->getProcAddress(QLatin1String("glGetActiveUniform"));//### REMOVE + glGetUniformLocation = (_glGetUniformLocation) ctx->getProcAddress(QLatin1String("glGetUniformLocation")); + glUniform4f = (_glUniform4f) ctx->getProcAddress(QLatin1String("glUniform4f")); //### REMOVE + glUniform4fv = (_glUniform4fv) ctx->getProcAddress(QLatin1String("glUniform4fv")); + glUniform3fv = (_glUniform3fv) ctx->getProcAddress(QLatin1String("glUniform3fv")); + glUniform2f = (_glUniform2f) ctx->getProcAddress(QLatin1String("glUniform2f")); //### REMOVE + glUniform2fv = (_glUniform2fv) ctx->getProcAddress(QLatin1String("glUniform2fv")); + glUniform1f = (_glUniform1f) ctx->getProcAddress(QLatin1String("glUniform1f")); //### REMOVE + glUniform1fv = (_glUniform1fv) ctx->getProcAddress(QLatin1String("glUniform1fv")); + glUniform1i = (_glUniform1i) ctx->getProcAddress(QLatin1String("glUniform1i")); + glUniform1iv = (_glUniform1iv) ctx->getProcAddress(QLatin1String("glUniform1iv")); + glUniformMatrix2fv = (_glUniformMatrix2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2fv")); + glUniformMatrix3fv = (_glUniformMatrix3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3fv")); + glUniformMatrix4fv = (_glUniformMatrix4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4fv")); + glUniformMatrix2x3fv = (_glUniformMatrix2x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2x3fv")); + glUniformMatrix2x4fv = (_glUniformMatrix2x4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2x4fv")); + glUniformMatrix3x2fv = (_glUniformMatrix3x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3x2fv")); + glUniformMatrix3x4fv = (_glUniformMatrix3x4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3x4fv")); + glUniformMatrix4x2fv = (_glUniformMatrix4x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x2fv")); + glUniformMatrix4x3fv = (_glUniformMatrix4x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x3fv")); + + glGetActiveAttrib = (_glGetActiveAttrib) ctx->getProcAddress(QLatin1String("glGetActiveAttrib")); //### REMOVE + glBindAttribLocation = (_glBindAttribLocation) ctx->getProcAddress(QLatin1String("glBindAttribLocation")); + glGetAttribLocation = (_glGetAttribLocation) ctx->getProcAddress(QLatin1String("glGetAttribLocation")); + glVertexAttrib1fv = (_glVertexAttrib1fv) ctx->getProcAddress(QLatin1String("glVertexAttrib1fv")); + glVertexAttrib2fv = (_glVertexAttrib2fv) ctx->getProcAddress(QLatin1String("glVertexAttrib2fv")); + glVertexAttrib3fv = (_glVertexAttrib3fv) ctx->getProcAddress(QLatin1String("glVertexAttrib3fv")); + glVertexAttrib4fv = (_glVertexAttrib4fv) ctx->getProcAddress(QLatin1String("glVertexAttrib4fv")); + glVertexAttribPointer = (_glVertexAttribPointer) ctx->getProcAddress(QLatin1String("glVertexAttribPointer")); + glDisableVertexAttribArray = (_glDisableVertexAttribArray) ctx->getProcAddress(QLatin1String("glDisableVertexAttribArray")); + glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArray")); + + glStencilOpSeparate = (_glStencilOpSeparate) ctx->getProcAddress(QLatin1String("glStencilOpSeparate")); //### Not really a glsl extension, but needed for gl2 + + } else { + // We may not have the standard shader functions, but we might + // have the older ARB functions instead. + glCreateShader = (_glCreateShader) ctx->getProcAddress(QLatin1String("glCreateShaderObjectARB")); + glShaderSource = (_glShaderSource) ctx->getProcAddress(QLatin1String("glShaderSourceARB")); + glShaderBinary = (_glShaderBinary) ctx->getProcAddress(QLatin1String("glShaderBinaryARB")); + glCompileShader = (_glCompileShader) ctx->getProcAddress(QLatin1String("glCompileShaderARB")); + glDeleteShader = (_glDeleteShader) ctx->getProcAddress(QLatin1String("glDeleteObjectARB")); + glIsShader = 0; + + glCreateProgram = (_glCreateProgram) ctx->getProcAddress(QLatin1String("glCreateProgramObjectARB")); + glAttachShader = (_glAttachShader) ctx->getProcAddress(QLatin1String("glAttachObjectARB")); + glDetachShader = (_glDetachShader) ctx->getProcAddress(QLatin1String("glDetachObjectARB")); + glLinkProgram = (_glLinkProgram) ctx->getProcAddress(QLatin1String("glLinkProgramARB")); + glUseProgram = (_glUseProgram) ctx->getProcAddress(QLatin1String("glUseProgramObjectARB")); + glDeleteProgram = (_glDeleteProgram) ctx->getProcAddress(QLatin1String("glDeleteObjectARB")); + glIsProgram = 0; + + glGetShaderInfoLog = (_glGetShaderInfoLog) ctx->getProcAddress(QLatin1String("glGetInfoLogARB")); + glGetShaderiv = (_glGetShaderiv) ctx->getProcAddress(QLatin1String("glGetObjectParameterivARB")); + glGetShaderSource = (_glGetShaderSource) ctx->getProcAddress(QLatin1String("glGetShaderSourceARB")); + glGetProgramiv = (_glGetProgramiv) ctx->getProcAddress(QLatin1String("glGetObjectParameterivARB")); + glGetProgramInfoLog = (_glGetProgramInfoLog) ctx->getProcAddress(QLatin1String("glGetInfoLogARB")); + + glGetActiveUniform = (_glGetActiveUniform) ctx->getProcAddress(QLatin1String("glGetActiveUniformARB"));//### REMOVE + glGetUniformLocation = (_glGetUniformLocation) ctx->getProcAddress(QLatin1String("glGetUniformLocationARB")); + glUniform4f = (_glUniform4f) ctx->getProcAddress(QLatin1String("glUniform4fARB")); //### REMOVE + glUniform4fv = (_glUniform4fv) ctx->getProcAddress(QLatin1String("glUniform4fvARB")); + glUniform3fv = (_glUniform3fv) ctx->getProcAddress(QLatin1String("glUniform3fvARB")); + glUniform2f = (_glUniform2f) ctx->getProcAddress(QLatin1String("glUniform2fARB")); //### REMOVE + glUniform2fv = (_glUniform2fv) ctx->getProcAddress(QLatin1String("glUniform2fvARB")); + glUniform1f = (_glUniform1f) ctx->getProcAddress(QLatin1String("glUniform1fARB")); //### REMOVE + glUniform1fv = (_glUniform1fv) ctx->getProcAddress(QLatin1String("glUniform1fvARB")); + glUniform1i = (_glUniform1i) ctx->getProcAddress(QLatin1String("glUniform1iARB")); + glUniform1iv = (_glUniform1iv) ctx->getProcAddress(QLatin1String("glUniform1ivARB")); + glUniformMatrix2fv = (_glUniformMatrix2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2fvARB")); + glUniformMatrix3fv = (_glUniformMatrix3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3fvARB")); + glUniformMatrix4fv = (_glUniformMatrix4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4fvARB")); + glUniformMatrix2x3fv = (_glUniformMatrix2x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2x3fvARB")); + glUniformMatrix2x4fv = (_glUniformMatrix2x4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix2x4fvARB")); + glUniformMatrix3x2fv = (_glUniformMatrix3x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3x2fvARB")); + glUniformMatrix3x4fv = (_glUniformMatrix3x4fv) ctx->getProcAddress(QLatin1String("glUniformMatrix3x4fvARB")); + glUniformMatrix4x2fv = (_glUniformMatrix4x2fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x2fvARB")); + glUniformMatrix4x3fv = (_glUniformMatrix4x3fv) ctx->getProcAddress(QLatin1String("glUniformMatrix4x3fvARB")); + + glGetActiveAttrib = (_glGetActiveAttrib) ctx->getProcAddress(QLatin1String("glGetActiveAttribARB")); //### REMOVE + glBindAttribLocation = (_glBindAttribLocation) ctx->getProcAddress(QLatin1String("glBindAttribLocationARB")); + glGetAttribLocation = (_glGetAttribLocation) ctx->getProcAddress(QLatin1String("glGetAttribLocationARB")); + glVertexAttrib1fv = (_glVertexAttrib1fv) ctx->getProcAddress(QLatin1String("glVertexAttrib1fvARB")); + glVertexAttrib2fv = (_glVertexAttrib2fv) ctx->getProcAddress(QLatin1String("glVertexAttrib2fvARB")); + glVertexAttrib3fv = (_glVertexAttrib3fv) ctx->getProcAddress(QLatin1String("glVertexAttrib3fvARB")); + glVertexAttrib4fv = (_glVertexAttrib4fv) ctx->getProcAddress(QLatin1String("glVertexAttrib4fvARB")); + glVertexAttribPointer = (_glVertexAttribPointer) ctx->getProcAddress(QLatin1String("glVertexAttribPointerARB")); + glDisableVertexAttribArray = (_glDisableVertexAttribArray) ctx->getProcAddress(QLatin1String("glDisableVertexAttribArrayARB")); + glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArrayARB")); + + glStencilOpSeparate = 0; //### Was never an ARB extension but went strait into OpenGL 2.0 + } + + // Note: glShaderBinary(), glIsShader(), glIsProgram(), and + // glUniformMatrixNxMfv() are optional, but all other functions + // are required. + + return glCreateShader && + glShaderSource && + glCompileShader && + glDeleteProgram && + glCreateProgram && + glAttachShader && + glDetachShader && + glLinkProgram && + glUseProgram && + glDeleteProgram && + glGetShaderInfoLog && + glGetShaderiv && + glGetShaderSource && + glGetProgramiv && + glGetProgramInfoLog && + glGetActiveUniform && //### REMOVE + glGetUniformLocation && + glUniform1f && //### REMOVE + glUniform1fv && + glUniform2f && //### REMOVE + glUniform2fv && + glUniform3fv && + glUniform4f && //### REMOVE + glUniform4fv && + glUniform1i && + glUniform1iv && + glUniformMatrix2fv && + glUniformMatrix3fv && + glUniformMatrix4fv && + glGetActiveAttrib && //### REMOVE + glBindAttribLocation && + glGetAttribLocation && + glVertexAttrib1fv && + glVertexAttrib2fv && + glVertexAttrib3fv && + glVertexAttrib4fv && + glVertexAttribPointer && + glDisableVertexAttribArray && + glEnableVertexAttribArray && + glStencilOpSeparate; +#endif } QT_END_NAMESPACE diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index cd35eb0..69632e7 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -96,8 +96,10 @@ typedef void (APIENTRY *_glProgramLocalParameter4fvARB) (GLenum, GLuint, const G // GLSL typedef GLuint (APIENTRY *_glCreateShader) (GLenum); typedef void (APIENTRY *_glShaderSource) (GLuint, GLsizei, const char **, const GLint *); +typedef void (APIENTRY *_glShaderBinary) (GLint, const GLuint*, GLenum, const void*, GLint); typedef void (APIENTRY *_glCompileShader) (GLuint); typedef void (APIENTRY *_glDeleteShader) (GLuint); +typedef GLboolean (APIENTRY *_glIsShader) (GLuint); typedef GLuint (APIENTRY *_glCreateProgram) (); typedef void (APIENTRY *_glAttachShader) (GLuint, GLuint); @@ -105,10 +107,13 @@ typedef void (APIENTRY *_glDetachShader) (GLuint, GLuint); typedef void (APIENTRY *_glLinkProgram) (GLuint); typedef void (APIENTRY *_glUseProgram) (GLuint); typedef void (APIENTRY *_glDeleteProgram) (GLuint); +typedef GLboolean (APIENTRY *_glIsProgram) (GLuint); typedef void (APIENTRY *_glGetShaderInfoLog) (GLuint, GLsizei, GLsizei *, char *); typedef void (APIENTRY *_glGetShaderiv) (GLuint, GLenum, GLint *); +typedef void (APIENTRY *_glGetShaderSource) (GLuint, GLsizei, GLsizei *, char *); typedef void (APIENTRY *_glGetProgramiv) (GLuint, GLenum, GLint *); +typedef void (APIENTRY *_glGetProgramInfoLog) (GLuint, GLsizei, GLsizei *, char *); typedef GLuint (APIENTRY *_glGetUniformLocation) (GLuint, const char*); typedef void (APIENTRY *_glUniform4fv) (GLint, GLsizei, const GLfloat *); @@ -116,6 +121,29 @@ typedef void (APIENTRY *_glUniform3fv) (GLint, GLsizei, const GLfloat *); typedef void (APIENTRY *_glUniform2fv) (GLint, GLsizei, const GLfloat *); typedef void (APIENTRY *_glUniform1fv) (GLint, GLsizei, const GLfloat *); typedef void (APIENTRY *_glUniform1i) (GLint, GLint); +typedef void (APIENTRY *_glUniform1iv) (GLint, GLsizei, const GLint *); +typedef void (APIENTRY *_glUniformMatrix2fv) (GLint, GLsizei, GLboolean, const GLfloat *); +typedef void (APIENTRY *_glUniformMatrix3fv) (GLint, GLsizei, GLboolean, const GLfloat *); +typedef void (APIENTRY *_glUniformMatrix4fv) (GLint, GLsizei, GLboolean, const GLfloat *); +typedef void (APIENTRY *_glUniformMatrix2x3fv) (GLint, GLsizei, GLboolean, const GLfloat *); +typedef void (APIENTRY *_glUniformMatrix2x4fv) (GLint, GLsizei, GLboolean, const GLfloat *); +typedef void (APIENTRY *_glUniformMatrix3x2fv) (GLint, GLsizei, GLboolean, const GLfloat *); +typedef void (APIENTRY *_glUniformMatrix3x4fv) (GLint, GLsizei, GLboolean, const GLfloat *); +typedef void (APIENTRY *_glUniformMatrix4x2fv) (GLint, GLsizei, GLboolean, const GLfloat *); +typedef void (APIENTRY *_glUniformMatrix4x3fv) (GLint, GLsizei, GLboolean, const GLfloat *); + +typedef void (APIENTRY *_glBindAttribLocation) (GLuint, GLuint, const char *); +typedef GLint (APIENTRY *_glGetAttribLocation) (GLuint, const char *); +typedef void (APIENTRY *_glVertexAttrib1fv) (GLuint, const GLfloat *); +typedef void (APIENTRY *_glVertexAttrib2fv) (GLuint, const GLfloat *); +typedef void (APIENTRY *_glVertexAttrib3fv) (GLuint, const GLfloat *); +typedef void (APIENTRY *_glVertexAttrib4fv) (GLuint, const GLfloat *); +typedef void (APIENTRY *_glVertexAttribPointer) (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); +typedef void (APIENTRY *_glDisableVertexAttribArray) (GLuint); +typedef void (APIENTRY *_glEnableVertexAttribArray) (GLuint); + +typedef void (APIENTRY *_glGetProgramBinaryOES) (GLuint, GLsizei, GLsizei *, GLenum *, void *); +typedef void (APIENTRY *_glProgramBinaryOES) (GLuint, GLenum, const void *, GLint); typedef void (APIENTRY *_glActiveStencilFaceEXT) (GLenum ); @@ -182,10 +210,13 @@ struct QGLExtensionFuncs qt_glGenProgramsARB = 0; qt_glProgramLocalParameter4fvARB = 0; +#if !defined(QT_OPENGL_ES_2) qt_glCreateShader = 0; qt_glShaderSource = 0; + qt_glShaderBinary = 0; qt_glCompileShader = 0; qt_glDeleteShader = 0; + qt_glIsShader = 0; qt_glCreateProgram = 0; qt_glAttachShader = 0; @@ -193,10 +224,13 @@ struct QGLExtensionFuncs qt_glLinkProgram = 0; qt_glUseProgram = 0; qt_glDeleteProgram = 0; + qt_glIsProgram = 0; qt_glGetShaderInfoLog = 0; qt_glGetShaderiv = 0; + qt_glGetShaderSource = 0; qt_glGetProgramiv = 0; + qt_glGetProgramInfoLog = 0; qt_glGetUniformLocation = 0; qt_glUniform4fv = 0; @@ -204,6 +238,32 @@ struct QGLExtensionFuncs qt_glUniform2fv = 0; qt_glUniform1fv = 0; qt_glUniform1i = 0; + qt_glUniform1iv = 0; + qt_glUniformMatrix2fv = 0; + qt_glUniformMatrix3fv = 0; + qt_glUniformMatrix4fv = 0; + qt_glUniformMatrix2x3fv = 0; + qt_glUniformMatrix2x4fv = 0; + qt_glUniformMatrix3x2fv = 0; + qt_glUniformMatrix3x4fv = 0; + qt_glUniformMatrix4x2fv = 0; + qt_glUniformMatrix4x3fv = 0; + + qt_glBindAttribLocation = 0; + qt_glGetAttribLocation = 0; + qt_glVertexAttrib1fv = 0; + qt_glVertexAttrib2fv = 0; + qt_glVertexAttrib3fv = 0; + qt_glVertexAttrib4fv = 0; + qt_glVertexAttribPointer = 0; + qt_glDisableVertexAttribArray = 0; + qt_glEnableVertexAttribArray = 0; +#else + qt_glslResolved = false; + + qt_glGetProgramBinaryOES = 0; + qt_glProgramBinaryOES = 0; +#endif qt_glActiveStencilFaceEXT = 0; @@ -261,11 +321,14 @@ struct QGLExtensionFuncs _glGenProgramsARB qt_glGenProgramsARB; _glProgramLocalParameter4fvARB qt_glProgramLocalParameter4fvARB; +#if !defined(QT_OPENGL_ES_2) // GLSL definitions _glCreateShader qt_glCreateShader; _glShaderSource qt_glShaderSource; + _glShaderBinary qt_glShaderBinary; _glCompileShader qt_glCompileShader; _glDeleteShader qt_glDeleteShader; + _glIsShader qt_glIsShader; _glCreateProgram qt_glCreateProgram; _glAttachShader qt_glAttachShader; @@ -273,10 +336,13 @@ struct QGLExtensionFuncs _glLinkProgram qt_glLinkProgram; _glUseProgram qt_glUseProgram; _glDeleteProgram qt_glDeleteProgram; + _glIsProgram qt_glIsProgram; _glGetShaderInfoLog qt_glGetShaderInfoLog; _glGetShaderiv qt_glGetShaderiv; + _glGetShaderSource qt_glGetShaderSource; _glGetProgramiv qt_glGetProgramiv; + _glGetProgramInfoLog qt_glGetProgramInfoLog; _glGetUniformLocation qt_glGetUniformLocation; _glUniform4fv qt_glUniform4fv; @@ -284,6 +350,32 @@ struct QGLExtensionFuncs _glUniform2fv qt_glUniform2fv; _glUniform1fv qt_glUniform1fv; _glUniform1i qt_glUniform1i; + _glUniform1iv qt_glUniform1iv; + _glUniformMatrix2fv qt_glUniformMatrix2fv; + _glUniformMatrix3fv qt_glUniformMatrix3fv; + _glUniformMatrix4fv qt_glUniformMatrix4fv; + _glUniformMatrix2x3fv qt_glUniformMatrix2x3fv; + _glUniformMatrix2x4fv qt_glUniformMatrix2x4fv; + _glUniformMatrix3x2fv qt_glUniformMatrix3x2fv; + _glUniformMatrix3x4fv qt_glUniformMatrix3x4fv; + _glUniformMatrix4x2fv qt_glUniformMatrix4x2fv; + _glUniformMatrix4x3fv qt_glUniformMatrix4x3fv; + + _glBindAttribLocation qt_glBindAttribLocation; + _glGetAttribLocation qt_glGetAttribLocation; + _glVertexAttrib1fv qt_glVertexAttrib1fv; + _glVertexAttrib2fv qt_glVertexAttrib2fv; + _glVertexAttrib3fv qt_glVertexAttrib3fv; + _glVertexAttrib4fv qt_glVertexAttrib4fv; + _glVertexAttribPointer qt_glVertexAttribPointer; + _glDisableVertexAttribArray qt_glDisableVertexAttribArray; + _glEnableVertexAttribArray qt_glEnableVertexAttribArray; +#else + bool qt_glslResolved; + + _glGetProgramBinaryOES qt_glGetProgramBinaryOES; + _glProgramBinaryOES qt_glProgramBinaryOES; +#endif _glActiveStencilFaceEXT qt_glActiveStencilFaceEXT; @@ -600,10 +692,14 @@ struct QGLExtensionFuncs #define glMapBufferARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glMapBufferARB #define glUnmapBufferARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUnmapBufferARB +#if !defined(QT_OPENGL_ES_2) + #define glCreateShader QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glCreateShader #define glShaderSource QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glShaderSource +#define glShaderBinary QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glShaderBinary #define glCompileShader QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glCompileShader #define glDeleteShader QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteShader +#define glIsShader QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glIsShader #define glCreateProgram QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glCreateProgram #define glAttachShader QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glAttachShader @@ -611,10 +707,13 @@ struct QGLExtensionFuncs #define glLinkProgram QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glLinkProgram #define glUseProgram QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUseProgram #define glDeleteProgram QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteProgram +#define glIsProgram QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glIsProgram #define glGetShaderInfoLog QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetShaderInfoLog #define glGetShaderiv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetShaderiv +#define glGetShaderSource QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetShaderSource #define glGetProgramiv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetProgramiv +#define glGetProgramInfoLog QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetProgramInfoLog #define glGetUniformLocation QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetUniformLocation #define glUniform4fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform4fv @@ -622,6 +721,33 @@ struct QGLExtensionFuncs #define glUniform2fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform2fv #define glUniform1fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1fv #define glUniform1i QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1i +#define glUniform1iv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniform1iv +#define glUniformMatrix2fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix2fv +#define glUniformMatrix3fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix3fv +#define glUniformMatrix4fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix4fv +#define glUniformMatrix2x3fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix2x3fv +#define glUniformMatrix2x4fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix2x4fv +#define glUniformMatrix3x2fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix3x2fv +#define glUniformMatrix3x4fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix3x4fv +#define glUniformMatrix4x2fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix4x2fv +#define glUniformMatrix4x3fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUniformMatrix4x3fv + +#define glBindAttribLocation QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindAttribLocation +#define glGetAttribLocation QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetAttribLocation +#define glVertexAttrib1fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glVertexAttrib1fv +#define glVertexAttrib2fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glVertexAttrib2fv +#define glVertexAttrib3fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glVertexAttrib3fv +#define glVertexAttrib4fv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glVertexAttrib4fv +#define glVertexAttribPointer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glVertexAttribPointer +#define glDisableVertexAttribArray QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDisableVertexAttribArray +#define glEnableVertexAttribArray QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glEnableVertexAttribArray + +#else // QT_OPENGL_ES_2 + +#define glGetProgramBinaryOES QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetProgramBinaryOES +#define glProgramBinaryOES QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glProgramBinaryOES + +#endif // QT_OPENGL_ES_2 #define glGetActiveAttrib QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetActiveAttrib #define glGetAttribLocation QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetAttribLocation diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 8a64515..87abf60 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -45,27 +45,12 @@ #include "qpaintengine_opengl_p.h" #include "qglpixelbuffer.h" -#include "qglextensions_p.h" +#include "qglshaderprogram.h" #include "qgl_p.h" #include "private/qapplication_p.h" -#ifndef GL_FRAGMENT_SHADER -#define GL_FRAGMENT_SHADER 0x8B30 -#endif - -#ifndef GL_COMPILE_STATUS -#define GL_COMPILE_STATUS 0x8B81 -#endif - -#ifndef GL_LINK_STATUS -#define GL_LINK_STATUS 0x8B82 -#endif - - - - QT_BEGIN_NAMESPACE @@ -79,110 +64,6 @@ void QGLPixmapFilterBase::drawImpl(QPainter *painter, const QPointF &pos, const processGL(painter, pos, src, source); } -QGLSLProgram::QGLSLProgram(const QString &src) - : ctx(QGLContext::currentContext()) -{ - if (!qt_resolve_glsl_extensions(const_cast(ctx))) { - qWarning("Failed to resolve GLSL functions"); - m_valid = false; - return; - } - - m_shader = glCreateShader(GL_FRAGMENT_SHADER); - - const QByteArray src_ba = src.toAscii(); - const char *src_cstr = src_ba.constData(); - - glShaderSource(m_shader, 1, &src_cstr, 0); - glCompileShader(m_shader); - glGetShaderiv(m_shader, GL_COMPILE_STATUS, &m_valid); - if (!m_valid) { - char data[4096]; - GLsizei len; - glGetShaderInfoLog(m_shader, 4096, &len, data); - qWarning("Failed to compile GLSL shader:\n%s\nCODE:\n%s\n", data, src_cstr); - return; - } - - m_program = glCreateProgram(); - glAttachShader(m_program, m_shader); - glLinkProgram(m_program); - glGetProgramiv(m_program, GL_LINK_STATUS, &m_valid); - if (!m_valid) { - char data[4096]; - GLsizei len; - glGetShaderInfoLog(m_shader, 4096, &len, data); - qWarning("Failed to link GLSL program:\n%s\nCODE:\n%s\n", data, src_cstr); - return; - } -} - -QGLSLProgram::~QGLSLProgram() -{ - glDeleteProgram(m_program); - glDeleteShader(m_shader); -} - -bool QGLSLProgram::success() const -{ - return m_valid; -} - -void QGLSLProgram::enable() -{ - glUseProgram(m_program); -} - -void QGLSLProgram::disable() -{ - glUseProgram(0); -} - -int QGLSLProgram::getUniformLocation(const QString &name) -{ - return glGetUniformLocation(m_program, name.toAscii().constData()); -} - -void QGLSLProgram::setUniform(int uniform, int value) -{ - enable(); - glUniform1i(uniform, value); -} - -void QGLSLProgram::setUniform(int uniform, qreal value) -{ - enable(); - GLfloat v[] = { value }; - glUniform1fv(uniform, 1, v); -} - -void QGLSLProgram::setUniform(int uniform, qreal v1, qreal v2) -{ - enable(); - GLfloat v[] = { v1, v2 }; - glUniform2fv(uniform, 1, v); -} - -void QGLSLProgram::setUniform(int uniform, qreal v1, qreal v2, qreal v3) -{ - enable(); - GLfloat v[] = { v1, v2, v3 }; - glUniform3fv(uniform, 1, v); -} - -void QGLSLProgram::setUniform(int uniform, qreal v1, qreal v2, qreal v3, qreal v4) -{ - enable(); - GLfloat v[] = { v1, v2, v3, v4 }; - glUniform4fv(uniform, 1, v); -} - -void QGLSLProgram::setUniform(int uniform, int count, float *v) -{ - enable(); - glUniform1fv(uniform, count, v); -} - class QGLPixmapColorizeFilter: public QGLPixmapFilter { public: @@ -192,8 +73,8 @@ protected: bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &pixmap, const QRectF &srcRect) const; private: - mutable QGLSLProgram m_program; - uint m_colorUniform; + mutable QGLShaderProgram m_program; + int m_colorUniform; }; class QGLPixmapConvolutionFilter: public QGLPixmapFilter @@ -206,11 +87,11 @@ protected: bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const; private: - QString generateConvolutionShader() const; + QByteArray generateConvolutionShader() const; - mutable QGLSLProgram *m_program; - mutable uint m_scaleUniform; - mutable uint m_matrixUniform; + mutable QGLShaderProgram *m_program; + mutable int m_scaleUniform; + mutable int m_matrixUniform; mutable int m_kernelWidth; mutable int m_kernelHeight; @@ -298,10 +179,12 @@ static const char *qt_gl_colorize_filter = "}"; QGLPixmapColorizeFilter::QGLPixmapColorizeFilter() - : m_program(QLatin1String(qt_gl_colorize_filter)) { - m_program.setUniform(m_program.getUniformLocation(QLatin1String("texture")), 0); // GL_TEXTURE_0 - m_colorUniform = m_program.getUniformLocation(QLatin1String("color")); + m_program.addShader(QGLShader::FragmentShader, qt_gl_colorize_filter); + m_program.link(); + m_program.enable(); + m_program.setUniformValue(m_program.uniformLocation("texture"), 0); // GL_TEXTURE_0 + m_colorUniform = m_program.uniformLocation("color"); } bool QGLPixmapColorizeFilter::processGL(QPainter *, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const @@ -309,10 +192,10 @@ bool QGLPixmapColorizeFilter::processGL(QPainter *, const QPointF &pos, const QP bindTexture(src); QColor col = color(); - m_program.setUniform(m_colorUniform, col.redF(), col.greenF(), col.blueF()); + m_program.enable(); + m_program.setUniformValue(m_colorUniform, col.redF(), col.greenF(), col.blueF()); QRectF target = (srcRect.isNull() ? QRectF(src.rect()) : srcRect).translated(pos); - m_program.enable(); qgl_drawTexture(target, src.width(), src.height(), srcRect); m_program.disable(); @@ -320,7 +203,7 @@ bool QGLPixmapColorizeFilter::processGL(QPainter *, const QPointF &pos, const QP } // generates convolution filter code for arbitrary sized kernel -QString QGLPixmapConvolutionFilter::generateConvolutionShader() const { +QByteArray QGLPixmapConvolutionFilter::generateConvolutionShader() const { QByteArray code; code.append("uniform sampler2D texture;\n"); code.append("uniform vec2 inv_texture_size;\n"); @@ -356,7 +239,7 @@ QString QGLPixmapConvolutionFilter::generateConvolutionShader() const { code.append(" }\n"); code.append(" gl_FragColor = sum;\n"); code.append("}"); - return QLatin1String(code); + return code; } QGLPixmapConvolutionFilter::QGLPixmapConvolutionFilter() @@ -388,10 +271,12 @@ bool QGLPixmapConvolutionFilter::processGL(QPainter *, const QPointF &pos, const m_kernelWidth = columns(); m_kernelHeight = rows(); - QString code = generateConvolutionShader(); - m_program = new QGLSLProgram(code); - m_scaleUniform = m_program->getUniformLocation(QLatin1String("inv_texture_size")); - m_matrixUniform = m_program->getUniformLocation(QLatin1String("matrix")); + QByteArray code = generateConvolutionShader(); + m_program = new QGLShaderProgram(); + m_program->addShader(QGLShader::FragmentShader, code); + m_program->link(); + m_scaleUniform = m_program->uniformLocation("inv_texture_size"); + m_matrixUniform = m_program->uniformLocation("matrix"); } const qreal *kernel = convolutionKernel(); @@ -401,10 +286,10 @@ bool QGLPixmapConvolutionFilter::processGL(QPainter *, const QPointF &pos, const const qreal iw = 1.0 / src.width(); const qreal ih = 1.0 / src.height(); - m_program->setUniform(m_scaleUniform, iw, ih); - m_program->setUniform(m_matrixUniform, m_kernelWidth * m_kernelHeight, conv); - m_program->enable(); + m_program->setUniformValue(m_scaleUniform, iw, ih); + m_program->setUniformValueArray(m_matrixUniform, conv, m_kernelWidth * m_kernelHeight, 1); + qgl_drawTexture(target, src.width(), src.height(), boundingRectFor(srcRect)); m_program->disable(); return true; diff --git a/src/opengl/qglpixmapfilter_p.h b/src/opengl/qglpixmapfilter_p.h index dc2eea6..d6742fc 100644 --- a/src/opengl/qglpixmapfilter_p.h +++ b/src/opengl/qglpixmapfilter_p.h @@ -87,35 +87,6 @@ public: } }; -class Q_OPENGL_EXPORT QGLSLProgram -{ -public: - QGLSLProgram(const QString &src); - ~QGLSLProgram(); - - bool success() const; - - void enable(); - void disable(); - - int getUniformLocation(const QString &name); - - void setUniform(int uniform, int value); - void setUniform(int uniform, qreal value); - void setUniform(int uniform, qreal v1, qreal v2); - void setUniform(int uniform, qreal v1, qreal v2, qreal v3); - void setUniform(int uniform, qreal v1, qreal v2, qreal v3, qreal v4); - void setUniform(int uniform, int count, float *v); - -private: - GLuint m_shader; - GLuint m_program; - - GLint m_valid; - - const QGLContext *ctx; -}; - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp new file mode 100644 index 0000000..934b5a5 --- /dev/null +++ b/src/opengl/qglshaderprogram.cpp @@ -0,0 +1,2828 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qglshaderprogram.h" +#include "qglextensions_p.h" +#include "qgl_p.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#if !defined(QT_OPENGL_ES_1_CL) + +/*! + \class QGLShaderProgram + \brief The QGLShaderProgram class allows OpenGL shader programs to be linked and used. + \since 4.6 + + \section1 Introduction + + This class supports shader programs written in the OpenGL Shading + Language (GLSL) and in the OpenGL/ES Shading Language (GLSL/ES). + + QGLShader and QGLShaderProgram shelter the programmer from the details of + compiling and linking vertex and fragment shaders. + + The following example creates a vertex shader program using the + supplied source \c{code}. Once compiled and linked, the shader + program is activated in the current QGLContext by calling + QGLShaderProgram::enable(): + + \code + QGLShader shader(QGLShader::VertexShader); + shader.setSourceCode(code); + + QGLShaderProgram program(context); + program.addShader(shader); + program.link(); + + program.enable(); + \endcode + + \section1 Writing portable shaders + + Shader programs can be difficult to reuse across OpenGL implementations + because of varying levels of support for standard vertex attributes and + uniform variables. In particular, GLSL/ES lacks all of the + standard variables that are present on desktop OpenGL systems: + \c{gl_Vertex}, \c{gl_Normal}, \c{gl_Color}, and so on. Desktop OpenGL + lacks the variable qualifiers \c{highp}, \c{mediump}, and \c{lowp}. + + The QGLShaderProgram class makes the process of writing portable shaders + easier by prefixing all shader programs with the following lines on + desktop OpenGL: + + \code + #define highp + #define mediump + #define lowp + \endcode + + This makes it possible to run most GLSL/ES shader programs + on desktop systems. The programmer should restrict themselves + to just features that are present in GLSL/ES, and avoid + standard variable names that only work on the desktop. + + \section1 Simple shader example + + \code + program.addShader(QGLShader::VertexShader, + "attribute highp vec4 vertex;\n" + "attribute mediump mat4 matrix;\n" + "void main(void)\n" + "{\n" + " gl_Position = matrix * vertex;\n" + "}"); + program.addShader(QGLShader::FragmentShader, + "uniform mediump vec4 color;\n" + "void main(void)\n" + "{\n" + " gl_FragColor = color;\n" + "}"); + program.link(); + program.enable(); + + int vertexLocation = program.attributeLocation("vertex"); + int matrixLocation = program.attributeLocation("matrix"); + int colorLocation = program.uniformLocation("color"); + \endcode + + With the above shader program active, we can draw a green triangle + as follows: + + \code + static GLfloat const triangleVertices[] = { + 60.0f, 10.0f, 0.0f, + 110.0f, 110.0f, 0.0f, + 10.0f, 110.0f, 0.0f + }; + + QColor color(0, 255, 0, 255); + + QMatrix4x4 pmvMatrix; + pmvMatrix.ortho(rect()); + + program.setAttributeArray(vertexLocation, triangleVertices, 3); + program.setUniformValue(matrixLocation, pmvMatrix); + program.setUniformValue(colorLocation, color); + + glDrawArrays(GL_TRIANGLES, 0, 3); + \endcode + + \section1 Partial shaders + + Desktop GLSL can attach an arbitrary number of vertex and fragment + shaders to a shader program. Embedded GLSL/ES on the other hand + supports only a single shader of each type on a shader program. + + Multiple shaders of the same type can be useful when large libraries + of shaders are needed. Common functions can be factored out into + library shaders that can be reused in multiple shader programs. + + To support this use of shaders, the application programmer can + create shaders with the QGLShader::PartialVertexShader and + QGLShader::PartialFragmentShader types. These types direct + QGLShader and QGLShaderProgram to delay shader compilation until + link time. + + When link() is called, the sources for the partial shaders are + concatenated, and a single vertex or fragment shader is compiled + and linked into the shader program. + + It is more efficient to use the QGLShader::VertexShader and + QGLShader::FragmentShader when there is only one shader of that + type in the program. + + \sa QGLShader +*/ + +/*! + \class QGLShader + \brief The QGLShader class allows OpenGL shaders to be compiled. + \since 4.6 + + This class supports shaders written in the OpenGL Shading Language (GLSL) + and in the OpenGL/ES Shading Language (GLSL/ES). + + QGLShader and QGLShaderProgram shelter the programmer from the details of + compiling and linking vertex and fragment shaders. + + \sa QGLShaderProgram +*/ + +/*! + \enum QGLShader::ShaderType + This enum specifies the type of QGLShader that is being created. + + \value VertexShader Vertex shader written in the OpenGL Shading Language (GLSL). + \value FragmentShader Fragment shader written in the OpenGL Shading Language (GLSL). + \value PartialVertexShader Partial vertex shader that will be concatenated with all other partial vertex shaders at link time. + \value PartialFragmentShader Partial fragment shader that will be concatenated with all other partial fragment shaders at link time. +*/ + +#ifndef GL_FRAGMENT_SHADER +#define GL_FRAGMENT_SHADER 0x8B30 +#endif +#ifndef GL_VERTEX_SHADER +#define GL_VERTEX_SHADER 0x8B31 +#endif +#ifndef GL_COMPILE_STATUS +#define GL_COMPILE_STATUS 0x8B81 +#endif +#ifndef GL_LINK_STATUS +#define GL_LINK_STATUS 0x8B82 +#endif +#ifndef GL_INFO_LOG_LENGTH +#define GL_INFO_LOG_LENGTH 0x8B84 +#endif +#ifndef GL_ACTIVE_UNIFORMS +#define GL_ACTIVE_UNIFORMS 0x8B86 +#endif +#ifndef GL_ACTIVE_UNIFORM_MAX_LENGTH +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#endif +#ifndef GL_ACTIVE_ATTRIBUTES +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#endif +#ifndef GL_ACTIVE_ATTRIBUTE_MAX_LENGTH +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#endif +#ifndef GL_CURRENT_VERTEX_ATTRIB +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#endif +#ifndef GL_SHADER_SOURCE_LENGTH +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#endif +#ifndef GL_SHADER_BINARY_FORMATS +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#endif +#ifndef GL_NUM_SHADER_BINARY_FORMATS +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#endif + +class QGLShaderPrivate +{ +public: + QGLShaderPrivate(QGLShader::ShaderType type, const QGLContext *ctx) + { + context = ctx; + shader = 0; + shaderType = type; + compiled = false; + isPartial = (type == QGLShader::PartialVertexShader || + type == QGLShader::PartialFragmentShader); + hasPartialSource = false; + } + + const QGLContext *context; + GLuint shader; + QGLShader::ShaderType shaderType; + bool compiled; + bool isPartial; + bool hasPartialSource; + QString errors; + QByteArray partialSource; + + bool create(); + bool compile(); +}; + +#define ctx context + +bool QGLShaderPrivate::create() +{ + if (isPartial) + return true; + if (!context) + context = QGLContext::currentContext(); + if (!context) + return false; + if (qt_resolve_glsl_extensions(const_cast(context))) { + if (shaderType == QGLShader::VertexShader) + shader = glCreateShader(GL_VERTEX_SHADER); + else + shader = glCreateShader(GL_FRAGMENT_SHADER); + if (!shader) { + qWarning() << "QGLShader: could not create shader"; + return false; + } + return true; + } else { + return false; + } +} + +bool QGLShaderPrivate::compile() +{ + // Partial shaders are compiled during QGLShaderProgram::link(). + if (isPartial && hasPartialSource) { + compiled = true; + return true; + } + if (!shader) + return false; + glCompileShader(shader); + GLint value = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &value); + compiled = (value != 0); + value = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value); + if (!compiled && value > 1) { + char *log = new char [value]; + GLint len; + glGetShaderInfoLog(shader, value, &len, log); + errors = QString::fromLatin1(log); + qWarning() << "QGLShader::compile:" << errors; + delete [] log; + } + return compiled; +} + +#undef ctx +#define ctx d->context + +/*! + Constructs a new QGLShader object of the specified \a type + and attaches it to \a parent. If shader programs are not supported, + then isValid() will return false. + + This constructor is normally followed by a call to setSourceCode() + or setSourceCodeFile(). + + The shader will be associated with the current QGLContext. + + \sa setSourceCode(), setSourceCodeFile(), isValid() +*/ +QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent) + : QObject(parent) +{ + d = new QGLShaderPrivate(type, QGLContext::currentContext()); + d->create(); +} + +/*! + Constructs a new QGLShader object from the source code in \a fileName + and attaches it to \a parent. If the filename ends in \c{.fsh}, + it is assumed to be a fragment shader, otherwise it is assumed to + be a vertex shader (normally the extension is \c{.vsh} for vertex shaders). + If the shader could not be loaded, then isValid() will return false. + + The shader will be associated with the current QGLContext. + + \sa isValid() +*/ +QGLShader::QGLShader(const QString& fileName, QObject *parent) + : QObject(parent) +{ + if (fileName.endsWith(QLatin1String(".fsh"), Qt::CaseInsensitive)) + d = new QGLShaderPrivate(QGLShader::FragmentShader, QGLContext::currentContext()); + else + d = new QGLShaderPrivate(QGLShader::VertexShader, QGLContext::currentContext()); + if (d->create() && !setSourceCodeFile(fileName)) { + if (d->shader) + glDeleteShader(d->shader); + d->shader = 0; + } +} + +/*! + Constructs a new QGLShader object of the specified \a type from the + source code in \a fileName and attaches it to \a parent. + If the shader could not be loaded, then isValid() will return false. + + The shader will be associated with the current QGLContext. + + \sa isValid() +*/ +QGLShader::QGLShader + (const QString& fileName, QGLShader::ShaderType type, QObject *parent) + : QObject(parent) +{ + d = new QGLShaderPrivate(type, QGLContext::currentContext()); + if (d->create() && !setSourceCodeFile(fileName)) { + if (d->shader) + glDeleteShader(d->shader); + d->shader = 0; + } +} + +/*! + Constructs a new QGLShader object of the specified \a type + and attaches it to \a parent. If shader programs are not supported, + then isValid() will return false. + + This constructor is normally followed by a call to setSourceCode() + or setSourceCodeFile(). + + The shader will be associated with \a context. + + \sa setSourceCode(), setSourceCodeFile(), isValid() +*/ +QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent) + : QObject(parent) +{ + d = new QGLShaderPrivate(type, context); + d->create(); +} + +/*! + Constructs a new QGLShader object from the source code in \a fileName + and attaches it to \a parent. If the filename ends in \c{.fsh}, + it is assumed to be a fragment shader, otherwise it is assumed to + be a vertex shader (normally the extension is \c{.vsh} for vertex shaders). + If the shader could not be loaded, then isValid() will return false. + + The shader will be associated with \a context. + + \sa isValid() +*/ +QGLShader::QGLShader(const QString& fileName, const QGLContext *context, QObject *parent) + : QObject(parent) +{ + if (fileName.endsWith(QLatin1String(".fsh"), Qt::CaseInsensitive)) + d = new QGLShaderPrivate(QGLShader::FragmentShader, context); + else + d = new QGLShaderPrivate(QGLShader::VertexShader, context); + if (d->create() && !setSourceCodeFile(fileName)) { + if (d->shader) + glDeleteShader(d->shader); + d->shader = 0; + } +} + +/*! + Constructs a new QGLShader object of the specified \a type from the + source code in \a fileName and attaches it to \a parent. + If the shader could not be loaded, then isValid() will return false. + + The shader will be associated with \a context. + + \sa isValid() +*/ +QGLShader::QGLShader + (const QString& fileName, QGLShader::ShaderType type, const QGLContext *context, QObject *parent) + : QObject(parent) +{ + d = new QGLShaderPrivate(type, context); + if (d->create() && !setSourceCodeFile(fileName)) { + if (d->shader) + glDeleteShader(d->shader); + d->shader = 0; + } +} + +/*! + Deletes this shader. If the shader has been attached to a + QGLShaderProgram object, then the actual shader will stay around + until the QGLShaderProgram is destroyed. +*/ +QGLShader::~QGLShader() +{ + if (d->shader) + glDeleteShader(d->shader); + delete d; +} + +/*! + Returns true if this shader is valid. Shaders become invalid + when they are destroyed and no longer attached to a QGLShaderProgram. +*/ +bool QGLShader::isValid() const +{ + if (d->isPartial && d->hasPartialSource) + return true; + if (!d->shader) + return false; +#if defined(QT_OPENGL_ES_2) + return glIsShader(d->shader); +#else + // glIsShader() may not exist on some systems. + return (!glIsShader || glIsShader(d->shader)); +#endif +} + +/*! + Returns the type of this shader. +*/ +QGLShader::ShaderType QGLShader::shaderType() const +{ + return d->shaderType; +} + +// The precision qualifiers are useful on OpenGL/ES systems, +// but usually not present on desktop systems. Define the +// keywords to empty strings on desktop systems. +#ifndef QT_OPENGL_ES +#define QGL_DEFINE_QUALIFIERS 1 +static const char qualifierDefines[] = + "#define lowp\n" + "#define mediump\n" + "#define highp\n"; +#endif + +/*! + Sets the \a source code for this shader and compiles it. + Returns true if the source was successfully compiled, false otherwise. + + If shaderType() is PartialVertexShader or PartialFragmentShader, + then this function will always return true, even if the source code + is invalid. Partial shaders are compiled when QGLShaderProgram::link() + is called. +*/ +bool QGLShader::setSourceCode(const char *source) +{ + if (d->isPartial) { + d->partialSource = QByteArray(source); + d->hasPartialSource = true; + return d->compile(); + } else if (d->shader) { + QVarLengthArray src; +#ifdef QGL_DEFINE_QUALIFIERS + src.append(qualifierDefines); +#endif + src.append(source); + glShaderSource(d->shader, src.size(), src.data(), 0); + return d->compile(); + } else { + return false; + } +} + +/*! + \overload + + Sets the \a source code for this shader and compiles it. + Returns true if the source was successfully compiled, false otherwise. + + If shaderType() is PartialVertexShader or PartialFragmentShader, + then this function will always return true, even if the source code + is invalid. Partial shaders are compiled when QGLShaderProgram::link() + is called. +*/ +bool QGLShader::setSourceCode(const QByteArray& source) +{ + return setSourceCode(source.constData()); +} + +/*! + \overload + + Sets the \a source code for this shader and compiles it. + Returns true if the source was successfully compiled, false otherwise. + + If shaderType() is PartialVertexShader or PartialFragmentShader, + then this function will always return true, even if the source code + is invalid. Partial shaders are compiled when QGLShaderProgram::link() + is called. +*/ +bool QGLShader::setSourceCode(const QString& source) +{ + return setSourceCode(source.toLatin1().constData()); +} + +/*! + Sets the source code for this shader to the contents of \a fileName + and compiles it. Returns true if the file could be opened and the + source compiled, false otherwise. + + If shaderType() is PartialVertexShader or PartialFragmentShader, + then this function will always return true, even if the source code + is invalid. Partial shaders are compiled when QGLShaderProgram::link() + is called. +*/ +bool QGLShader::setSourceCodeFile(const QString& fileName) +{ + if (!d->shader) + return false; + + QFile file(fileName); + if (!file.open(QFile::ReadOnly)) { + qWarning() << "QGLShader: Unable to open file" << fileName; + return false; + } + + QByteArray contents = file.readAll(); + return setSourceCode(contents.constData()); +} + +/*! + Sets the binary code for this shader to the \a length bytes from + the array \a binary. The \a format specifies how the binary data + should be interpreted by the OpenGL engine. Returns true if the + binary was set on the shader; false otherwise. + + This function cannot be used with PartialVertexShader or + PartialFragmentShader. + + \sa shaderBinaryFormats() +*/ +bool QGLShader::setBinaryCode(GLenum format, const void *binary, int length) +{ +#if !defined(QT_OPENGL_ES_2) + if (!glShaderBinary) + return false; +#endif + if (d->isPartial || !d->shader) + return false; + glGetError(); // Clear error state. + glShaderBinary(1, &(d->shader), format, binary, length); + return (glGetError() == GL_NO_ERROR); +} + +/*! + Sets the binary code for this shader to the \a length bytes from + the array \a binary. The \a format specifies how the binary data + should be interpreted by the OpenGL engine. Returns true if the + binary was set on the shader; false otherwise. + + The \a otherShader will also have binary code set on it. This is + for the case where \a binary contains both vertex and fragment + shader code. + + This function cannot be used with PartialVertexShader or + PartialFragmentShader. + + \sa shaderBinaryFormats() +*/ +bool QGLShader::setBinaryCode + (QGLShader& otherShader, GLenum format, const void *binary, int length) +{ +#if !defined(QT_OPENGL_ES_2) + if (!glShaderBinary) + return false; +#endif + if (d->isPartial || !d->shader) + return false; + if (otherShader.d->isPartial || !otherShader.d->shader) + return false; + glGetError(); // Clear error state. + GLuint shaders[2]; + shaders[0] = d->shader; + shaders[1] = otherShader.d->shader; + glShaderBinary(2, shaders, format, binary, length); + return (glGetError() == GL_NO_ERROR); +} + +/*! + Returns a list of all binary formats that are supported by + setBinaryCode() on this system. + + \sa setBinaryCode() +*/ +QList QGLShader::shaderBinaryFormats() +{ + GLint num; + QList list; + glGetError(); // Clear error state. + glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &num); + if (glGetError() != GL_NO_ERROR || num <= 0) + return list; + QVarLengthArray formats(num); + glGetIntegerv(GL_SHADER_BINARY_FORMATS, formats.data()); + for (GLint i = 0; i < num; ++i) + list += (GLenum)(formats[i]); + return list; +} + +/*! + Returns the source code for this shader. + + \sa setSourceCode() +*/ +QByteArray QGLShader::sourceCode() const +{ + if (d->isPartial) + return d->partialSource; + if (!d->shader) + return QByteArray(); + GLint size = 0; + glGetShaderiv(d->shader, GL_SHADER_SOURCE_LENGTH, &size); + if (size <= 0) + return QByteArray(); + GLint len = 0; + char *source = new char [size]; + glGetShaderSource(d->shader, size, &len, source); + QByteArray src(source); + delete [] source; + return src; +} + +/*! + Returns true if this shader has been compiled; false otherwise. + + \sa setSourceCode() +*/ +bool QGLShader::isCompiled() const +{ + return d->compiled; +} + +/*! + Returns the errors that occurred during the last compile. + + \sa setSourceCode() +*/ +QString QGLShader::errors() const +{ + return d->errors; +} + +/*! + Returns the OpenGL identifier associated with this shader. + + If shaderType() is PartialVertexShader or PartialFragmentShader, + this function will always return zero. Partial shaders are + created and compiled when QGLShaderProgram::link() is called. + + \sa QGLShaderProgram::programId() +*/ +GLuint QGLShader::shaderId() const +{ + return d->shader; +} + +#undef ctx +#define ctx context + +class QGLShaderProgramPrivate +{ +public: + QGLShaderProgramPrivate(const QGLContext *ctx) + { + context = ctx; + program = 0; + linked = false; + inited = false; + hasPartialShaders = false; + vertexShader = 0; + fragmentShader = 0; + } + ~QGLShaderProgramPrivate() + { + if (program) + glDeleteProgram(program); + } + + const QGLContext *context; + GLuint program; + bool linked; + bool inited; + bool hasPartialShaders; + QString errors; + QList shaders; + QList anonShaders; + QGLShader *vertexShader; + QGLShader *fragmentShader; +}; + +#undef ctx +#define ctx d->context + +/*! + Constructs a new shader program and attaches it to \a parent. + The program will be invalid until addShader() is called. + + The shader program will be associated with the current QGLContext. + + \sa isValid(), addShader() +*/ +QGLShaderProgram::QGLShaderProgram(QObject *parent) + : QObject(parent) +{ + d = new QGLShaderProgramPrivate(QGLContext::currentContext()); +} + +/*! + Constructs a new shader program and attaches it to \a parent. + The program will be invalid until addShader() is called. + + The shader program will be associated with \a context. + + \sa isValid(), addShader() +*/ +QGLShaderProgram::QGLShaderProgram(const QGLContext *context, QObject *parent) + : QObject(parent) +{ + d = new QGLShaderProgramPrivate(context); +} + +/*! + Deletes this shader program. +*/ +QGLShaderProgram::~QGLShaderProgram() +{ + delete d; +} + +bool QGLShaderProgram::init() +{ + if (d->program || d->inited) + return true; + d->inited = true; + if (!d->context) + d->context = QGLContext::currentContext(); + if (!d->context) + return false; + if (qt_resolve_glsl_extensions(const_cast(d->context))) { + d->program = glCreateProgram(); + if (!(d->program)) { + qWarning() << "QGLShaderProgram: could not create shader program"; + return false; + } + return true; + } else { + qWarning() << "QGLShaderProgram: shader programs are not supported"; + return false; + } +} + +/*! + Returns true if this shader program object is valid, false otherwise. +*/ +bool QGLShaderProgram::isValid() const +{ + if (!d->program) + return false; +#if defined(QT_OPENGL_ES_2) + return glIsProgram(d->program); +#else + // glIsProgram() may not exist on some systems. + return (!glIsProgram || glIsProgram(d->program)); +#endif +} + +/*! + Adds a compiled \a shader to this shader program. Returns true + if the shader could be added, or false otherwise. + + Ownership of the \a shader object remains with the caller. + It will not be deleted when this QGLShaderProgram instance + is deleted. This allows the caller to add the same shader + to multiple shader programs. + + \sa removeShader(), link(), removeAllShaders() +*/ +bool QGLShaderProgram::addShader(QGLShader *shader) +{ + if (!init()) + return false; + if (d->shaders.contains(shader)) + return true; // Already added to this shader program. + if (d->program && shader && shader->d->shader) { + if (!shader->d->compiled) + return false; + if (!shader->d->isPartial) + glAttachShader(d->program, shader->d->shader); + else + d->hasPartialShaders = true; + d->linked = false; // Program needs to be relinked. + d->shaders.append(shader); + return true; + } else { + return false; + } +} + +/*! + Compiles \a source as a shader of the specified \a type and + adds it to this shader program. Returns true if compilation + was successful, false otherwise. The compilation errors + will be made available via errors(). + + This function is intended to be a short-cut for quickly + adding vertex and fragment shaders to a shader program without + creating an instance of QGLShader first. + + \sa removeShader(), link(), errors(), removeAllShaders() +*/ +bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const char *source) +{ + if (!init()) + return false; + QGLShader *shader = new QGLShader(type, this); + if (!shader->setSourceCode(source)) { + d->errors = shader->errors(); + delete shader; + return false; + } + d->anonShaders.append(shader); + return addShader(shader); +} + +/*! + \overload + + Compiles \a source as a shader of the specified \a type and + adds it to this shader program. Returns true if compilation + was successful, false otherwise. The compilation errors + will be made available via errors(). + + This function is intended to be a short-cut for quickly + adding vertex and fragment shaders to a shader program without + creating an instance of QGLShader first. + + \sa removeShader(), link(), errors(), removeAllShaders() +*/ +bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const QByteArray& source) +{ + return addShader(type, source.constData()); +} + +/*! + \overload + + Compiles \a source as a shader of the specified \a type and + adds it to this shader program. Returns true if compilation + was successful, false otherwise. The compilation errors + will be made available via errors(). + + This function is intended to be a short-cut for quickly + adding vertex and fragment shaders to a shader program without + creating an instance of QGLShader first. + + \sa removeShader(), link(), errors(), removeAllShaders() +*/ +bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const QString& source) +{ + return addShader(type, source.toLatin1().constData()); +} + +/*! + Removes \a shader from this shader program. The object is not deleted. + + \sa addShader(), link(), removeAllShaders() +*/ +void QGLShaderProgram::removeShader(QGLShader *shader) +{ + if (d->program && shader && shader->d->shader) { + glDetachShader(d->program, shader->d->shader); + d->linked = false; // Program needs to be relinked. + } + d->shaders.removeAll(shader); + d->anonShaders.removeAll(shader); +} + +/*! + Returns a list of all shaders that have been added to this shader + program using addShader(). + + \sa addShader(), removeShader() +*/ +QList QGLShaderProgram::shaders() const +{ + return d->shaders; +} + +/*! + Removes all of the shaders that were added to this program previously. + The QGLShader objects for the shaders will not be deleted if they + were constructed externally. QGLShader objects that are constructed + internally by QGLShaderProgram will be deleted. + + \sa addShader(), removeShader() +*/ +void QGLShaderProgram::removeAllShaders() +{ + foreach (QGLShader *shader, d->shaders) { + if (d->program && shader && shader->d->shader) + glDetachShader(d->program, shader->d->shader); + } + foreach (QGLShader *shader, d->anonShaders) { + // Delete shader objects that were created anonymously. + delete shader; + } + d->shaders.clear(); + d->anonShaders.clear(); + d->linked = false; // Program needs to be relinked. +} + +#if defined(QT_OPENGL_ES_2) + +#ifndef GL_PROGRAM_BINARY_LENGTH_OES +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#endif +#ifndef GL_NUM_PROGRAM_BINARY_FORMATS_OES +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#endif +#ifndef GL_PROGRAM_BINARY_FORMATS_OES +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +#endif + +#endif + +/*! + Returns the program binary associated with this shader program. + The numeric identifier of the program binary format is returned + in \a format. The \c OES_get_program_binary extension will need + to be supported by the system for binary retrieval to succeed. + + Returns an empty QByteArray if the program binary cannot be + retrieved on this system, or the shader program has not yet + been linked. + + The returned binary can be supplied to setProgramBinary() on the + same machine at some future point to reload the program. It contains + the compiled code of all of the shaders that were attached to the + program at the time programBinary() is called. + + \sa setProgramBinary(), programBinaryFormats() +*/ +QByteArray QGLShaderProgram::programBinary(int *format) const +{ +#if defined(QT_OPENGL_ES_2) + if (!isLinked()) + return QByteArray(); + + // Get the length of the binary data, bailing out if there is none. + GLint length = 0; + glGetProgramiv(d->program, GL_PROGRAM_BINARY_LENGTH_OES, &length); + if (length <= 0) + return QByteArray(); + + // Retrieve the binary data. + QByteArray binary(length, 0); + GLenum binaryFormat; + glGetProgramBinaryOES(d->program, length, 0, &binaryFormat, binary.data()); + if (format) + *format = (int)binaryFormat; + return binary; +#else + Q_UNUSED(format); + return QByteArray(); +#endif +} + +/*! + Sets the \a binary for this shader program according to \a format. + Returns true if the binary was set, or false if the binary format + is not supported or this system does not support program binaries. + The program will be linked if the load succeeds. + + \sa programBinary(), programBinaryFormats(), isLinked() +*/ +bool QGLShaderProgram::setProgramBinary(int format, const QByteArray& binary) +{ +#if defined(QT_OPENGL_ES_2) + // Load the binary and check that it was linked correctly. + glProgramBinaryOES(d->program, (GLenum)format, + binary.constData(), binary.size()); + GLint value = 0; + glGetProgramiv(d->program, GL_LINK_STATUS, &value); + d->linked = (value != 0); + value = 0; + glGetProgramiv(d->program, GL_INFO_LOG_LENGTH, &value); + d->errors = QString(); + if (value > 1) { + char *log = new char [value]; + GLint len; + glGetProgramInfoLog(d->program, value, &len, log); + d->errors = QString::fromLatin1(log); + qWarning() << "QGLShaderProgram::setProgramBinary:" << d->errors; + delete [] log; + } + return d->linked; +#else + Q_UNUSED(format); + Q_UNUSED(binary); + return false; +#endif +} + +/*! + Returns the list of program binary formats that are accepted by + this system for use with setProgramBinary(). + + \sa programBinary, setProgramBinary() +*/ +QList QGLShaderProgram::programBinaryFormats() +{ +#if defined(QT_OPENGL_ES_2) + GLint count = 0; + glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES, &count); + if (count <= 0) + return QList(); + QVector list; + list.resize(count); + glGetIntegerv(GL_PROGRAM_BINARY_FORMATS_OES, list.data()); + return list.toList(); +#else + return QList(); +#endif +} + +/*! + Links together the shaders that were added to this program with + addShader(). Returns true if the link was successful or + false otherwise. If the link failed, the error messages can + be retrieved with errors(). + + Subclasses can override this function to initialize attributes + and uniform variables for use in specific shader programs. + + If the shader program was already linked, calling this + function again will force it to be re-linked. + + \sa addShader(), errors() +*/ +bool QGLShaderProgram::link() +{ + if (!d->program) + return false; + if (d->hasPartialShaders) { + // Compile the partial vertex and fragment shaders. + QByteArray vertexSource; + QByteArray fragmentSource; + foreach (QGLShader *shader, d->shaders) { + if (shader->shaderType() == QGLShader::PartialVertexShader) + vertexSource += shader->sourceCode(); + else if (shader->shaderType() == QGLShader::PartialFragmentShader) + fragmentSource += shader->sourceCode(); + } + if (vertexSource.isEmpty()) { + if (d->vertexShader) { + glDetachShader(d->program, d->vertexShader->d->shader); + delete d->vertexShader; + d->vertexShader = 0; + } + } else { + if (!d->vertexShader) { + d->vertexShader = + new QGLShader(QGLShader::VertexShader, this); + } + if (!d->vertexShader->setSourceCode(vertexSource)) { + d->errors = d->vertexShader->errors(); + return false; + } + glAttachShader(d->program, d->vertexShader->d->shader); + } + if (fragmentSource.isEmpty()) { + if (d->fragmentShader) { + glDetachShader(d->program, d->fragmentShader->d->shader); + delete d->fragmentShader; + d->fragmentShader = 0; + } + } else { + if (!d->fragmentShader) { + d->fragmentShader = + new QGLShader(QGLShader::FragmentShader, this); + } + if (!d->fragmentShader->setSourceCode(fragmentSource)) { + d->errors = d->fragmentShader->errors(); + return false; + } + glAttachShader(d->program, d->fragmentShader->d->shader); + } + } + glLinkProgram(d->program); + GLint value = 0; + glGetProgramiv(d->program, GL_LINK_STATUS, &value); + d->linked = (value != 0); + value = 0; + glGetProgramiv(d->program, GL_INFO_LOG_LENGTH, &value); + d->errors = QString(); + if (value > 1) { + char *log = new char [value]; + GLint len; + glGetProgramInfoLog(d->program, value, &len, log); + d->errors = QString::fromLatin1(log); + qWarning() << "QGLShaderProgram::link:" << d->errors; + delete [] log; + } + return d->linked; +} + +/*! + Returns true if this shader program has been linked; false otherwise. + + \sa link() +*/ +bool QGLShaderProgram::isLinked() const +{ + return d->linked; +} + +/*! + Returns the errors that occurred during the last link() + or addShader() with explicitly specified source code. + + \sa link() +*/ +QString QGLShaderProgram::errors() const +{ + return d->errors; +} + +/*! + Enable use of this shader program in the currently active QGLContext. + Returns true if the program was successfully enabled; false + otherwise. If the shader program has not yet been linked, + or it needs to be re-linked, this function will call link(). + + \sa link(), disable() +*/ +bool QGLShaderProgram::enable() +{ + if (!d->program) + return false; + if (!d->linked && !link()) + return false; + glUseProgram(d->program); + return true; +} + +/*! + Disables this shader program in the currently active QGLContext. + This is equivalent to calling \c{glUseProgram(0)}. + + \sa enable() +*/ +void QGLShaderProgram::disable() +{ +#if defined(QT_OPENGL_ES_2) + glUseProgram(0); +#else + if (glUseProgram) + glUseProgram(0); +#endif +} + +/*! + Returns the OpenGL identifier associated with this shader program. + + \sa QGLShader::shaderId() +*/ +GLuint QGLShaderProgram::programId() const +{ + return d->program; +} + +/*! + Binds the attribute \a name to the specified \a location. This + function can be called before or after the program has been linked. + Any attributes that have not been explicitly bound when the program + is linked will be assigned locations automatically. + + \sa attributeLocation() +*/ +void QGLShaderProgram::bindAttributeLocation(const char *name, int location) +{ + glBindAttribLocation(d->program, location, name); +} + +/*! + \overload + + Binds the attribute \a name to the specified \a location. This + function can be called before or after the program has been linked. + Any attributes that have not been explicitly bound when the program + is linked will be assigned locations automatically. + + \sa attributeLocation() +*/ +void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location) +{ + glBindAttribLocation(d->program, location, name.constData()); +} + +/*! + \overload + + Binds the attribute \a name to the specified \a location. This + function can be called before or after the program has been linked. + Any attributes that have not been explicitly bound when the program + is linked will be assigned locations automatically. + + \sa attributeLocation() +*/ +void QGLShaderProgram::bindAttributeLocation(const QString& name, int location) +{ + glBindAttribLocation(d->program, location, name.toLatin1().constData()); +} + +/*! + Returns the location of the attribute \a name within this shader + program's parameter list. Returns -1 if \a name is not a valid + attribute for this shader program. + + \sa uniformLocation(), bindAttributeLocation() +*/ +int QGLShaderProgram::attributeLocation(const char *name) const +{ + if (d->linked) { + return glGetAttribLocation(d->program, name); + } else { + qWarning() << "QGLShaderProgram::attributeLocation(" << name + << "): shader program is not linked"; + return -1; + } +} + +/*! + \overload + + Returns the location of the attribute \a name within this shader + program's parameter list. Returns -1 if \a name is not a valid + attribute for this shader program. + + \sa uniformLocation(), bindAttributeLocation() +*/ +int QGLShaderProgram::attributeLocation(const QByteArray& name) const +{ + return attributeLocation(name.constData()); +} + +/*! + \overload + + Returns the location of the attribute \a name within this shader + program's parameter list. Returns -1 if \a name is not a valid + attribute for this shader program. + + \sa uniformLocation(), bindAttributeLocation() +*/ +int QGLShaderProgram::attributeLocation(const QString& name) const +{ + return attributeLocation(name.toLatin1().constData()); +} + +/*! + Sets the attribute at \a location in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(int location, GLfloat value) +{ + if (location != -1) + glVertexAttrib1fv(location, &value); +} + +/*! + \overload + + Sets the attribute called \a name in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(const char *name, GLfloat value) +{ + setAttributeValue(attributeLocation(name), value); +} + +/*! + Sets the attribute at \a location in the current context to + the 2D vector (\a x, \a y). + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y) +{ + if (location != -1) { + GLfloat values[2] = {x, y}; + glVertexAttrib2fv(location, values); + } +} + +/*! + \overload + + Sets the attribute called \a name in the current context to + the 2D vector (\a x, \a y). + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(const char *name, GLfloat x, GLfloat y) +{ + setAttributeValue(attributeLocation(name), x, y); +} + +/*! + Sets the attribute at \a location in the current context to + the 3D vector (\a x, \a y, \a z). + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue + (int location, GLfloat x, GLfloat y, GLfloat z) +{ + if (location != -1) { + GLfloat values[3] = {x, y, z}; + glVertexAttrib3fv(location, values); + } +} + +/*! + \overload + + Sets the attribute called \a name in the current context to + the 3D vector (\a x, \a y, \a z). + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue + (const char *name, GLfloat x, GLfloat y, GLfloat z) +{ + setAttributeValue(attributeLocation(name), x, y, z); +} + +/*! + Sets the attribute at \a location in the current context to + the 4D vector (\a x, \a y, \a z, \a w). + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue + (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + if (location != -1) { + GLfloat values[4] = {x, y, z, w}; + glVertexAttrib4fv(location, values); + } +} + +/*! + \overload + + Sets the attribute called \a name in the current context to + the 4D vector (\a x, \a y, \a z, \a w). + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue + (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + setAttributeValue(attributeLocation(name), x, y, z, w); +} + +/*! + Sets the attribute at \a location in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value) +{ + if (location != -1) + glVertexAttrib2fv(location, reinterpret_cast(&value)); +} + +/*! + \overload + + Sets the attribute called \a name in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(const char *name, const QVector2D& value) +{ + setAttributeValue(attributeLocation(name), value); +} + +/*! + Sets the attribute at \a location in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value) +{ + if (location != -1) + glVertexAttrib3fv(location, reinterpret_cast(&value)); +} + +/*! + \overload + + Sets the attribute called \a name in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(const char *name, const QVector3D& value) +{ + setAttributeValue(attributeLocation(name), value); +} + +/*! + Sets the attribute at \a location in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value) +{ + if (location != -1) + glVertexAttrib4fv(location, reinterpret_cast(&value)); +} + +/*! + \overload + + Sets the attribute called \a name in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(const char *name, const QVector4D& value) +{ + setAttributeValue(attributeLocation(name), value); +} + +/*! + Sets the attribute at \a location in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(int location, const QColor& value) +{ + if (location != -1) { + GLfloat values[4] = {value.redF(), value.greenF(), value.blueF(), value.alphaF()}; + glVertexAttrib4fv(location, values); + } +} + +/*! + \overload + + Sets the attribute called \a name in the current context to \a value. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue(const char *name, const QColor& value) +{ + setAttributeValue(attributeLocation(name), value); +} + +/*! + Sets the attribute at \a location in the current context to the + contents of \a values, which contains \a columns elements, each + consisting of \a rows elements. The \a rows value should be + 1, 2, 3, or 4. This function is typically used to set matrix + values and column vectors. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue + (int location, const GLfloat *values, int columns, int rows) +{ + if (rows < 1 || rows > 4) { + qWarning() << "QGLShaderProgram::setAttributeValue: rows" << rows << "not supported"; + return; + } + if (location != -1) { + while (columns-- > 0) { + if (rows == 1) + glVertexAttrib1fv(location, values); + else if (rows == 2) + glVertexAttrib2fv(location, values); + else if (rows == 3) + glVertexAttrib3fv(location, values); + else + glVertexAttrib4fv(location, values); + values += rows; + ++location; + } + } +} + +/*! + \overload + + Sets the attribute called \a name in the current context to the + contents of \a values, which contains \a columns elements, each + consisting of \a rows elements. The \a rows value should be + 1, 2, 3, or 4. This function is typically used to set matrix + values and column vectors. + + \sa setUniformValue() +*/ +void QGLShaderProgram::setAttributeValue + (const char *name, const GLfloat *values, int columns, int rows) +{ + setAttributeValue(attributeLocation(name), values, columns, rows); +} + +/*! + Sets an array of vertex \a values on the attribute at \a location + in this shader program. The \a size indicates the number of + components per vertex (1, 2, 3, or 4), and the \a stride indicates + the number of bytes between vertices. A default \a stride value + of zero indicates that the vertices are densely packed in \a values. + + \sa setAttributeValue(), setUniformValue(), disableAttributeArray() +*/ +void QGLShaderProgram::setAttributeArray + (int location, const GLfloat *values, int size, int stride) +{ + if (location != -1) { + glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, + stride, values); + glEnableVertexAttribArray(location); + } +} + +/*! + Sets an array of 2D vertex \a values on the attribute at \a location + in this shader program. The \a stride indicates the number of bytes + between vertices. A default \a stride value of zero indicates that + the vertices are densely packed in \a values. + + \sa setAttributeValue(), setUniformValue(), disableAttributeArray() +*/ +void QGLShaderProgram::setAttributeArray + (int location, const QVector2D *values, int stride) +{ + if (location != -1) { + glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, + stride, values); + glEnableVertexAttribArray(location); + } +} + +/*! + Sets an array of 3D vertex \a values on the attribute at \a location + in this shader program. The \a stride indicates the number of bytes + between vertices. A default \a stride value of zero indicates that + the vertices are densely packed in \a values. + + \sa setAttributeValue(), setUniformValue(), disableAttributeArray() +*/ +void QGLShaderProgram::setAttributeArray + (int location, const QVector3D *values, int stride) +{ + if (location != -1) { + glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, + stride, values); + glEnableVertexAttribArray(location); + } +} + +/*! + Sets an array of 4D vertex \a values on the attribute at \a location + in this shader program. The \a stride indicates the number of bytes + between vertices. A default \a stride value of zero indicates that + the vertices are densely packed in \a values. + + \sa setAttributeValue(), setUniformValue(), disableAttributeArray() +*/ +void QGLShaderProgram::setAttributeArray + (int location, const QVector4D *values, int stride) +{ + if (location != -1) { + glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, + stride, values); + glEnableVertexAttribArray(location); + } +} + +/*! + \overload + + Sets an array of vertex \a values on the attribute called \a name + in this shader program. The \a size indicates the number of + components per vertex (1, 2, 3, or 4), and the \a stride indicates + the number of bytes between vertices. A default \a stride value + of zero indicates that the vertices are densely packed in \a values. + + \sa setAttributeValue(), setUniformValue(), disableAttributeArray() +*/ +void QGLShaderProgram::setAttributeArray + (const char *name, const GLfloat *values, int size, int stride) +{ + setAttributeArray(attributeLocation(name), values, size, stride); +} + +/*! + \overload + + Sets an array of 2D vertex \a values on the attribute called \a name + in this shader program. The \a stride indicates the number of bytes + between vertices. A default \a stride value of zero indicates that + the vertices are densely packed in \a values. + + \sa setAttributeValue(), setUniformValue(), disableAttributeArray() +*/ +void QGLShaderProgram::setAttributeArray + (const char *name, const QVector2D *values, int stride) +{ + setAttributeArray(attributeLocation(name), values, stride); +} + +/*! + \overload + + Sets an array of 3D vertex \a values on the attribute called \a name + in this shader program. The \a stride indicates the number of bytes + between vertices. A default \a stride value of zero indicates that + the vertices are densely packed in \a values. + + \sa setAttributeValue(), setUniformValue(), disableAttributeArray() +*/ +void QGLShaderProgram::setAttributeArray + (const char *name, const QVector3D *values, int stride) +{ + setAttributeArray(attributeLocation(name), values, stride); +} + +/*! + \overload + + Sets an array of 4D vertex \a values on the attribute called \a name + in this shader program. The \a stride indicates the number of bytes + between vertices. A default \a stride value of zero indicates that + the vertices are densely packed in \a values. + + \sa setAttributeValue(), setUniformValue(), disableAttributeArray() +*/ +void QGLShaderProgram::setAttributeArray + (const char *name, const QVector4D *values, int stride) +{ + setAttributeArray(attributeLocation(name), values, stride); +} + +/*! + Disables the vertex array at \a location in this shader program + that was enabled by a previous call to setAttributeArray(). + + \sa setAttributeArray(), setAttributeValue(), setUniformValue() +*/ +void QGLShaderProgram::disableAttributeArray(int location) +{ + if (location != -1) + glDisableVertexAttribArray(location); +} + +/*! + \overload + + Disables the vertex array called \a name in this shader program + that was enabled by a previous call to setAttributeArray(). + + \sa setAttributeArray(), setAttributeValue(), setUniformValue() +*/ +void QGLShaderProgram::disableAttributeArray(const char *name) +{ + disableAttributeArray(attributeLocation(name)); +} + +/*! + Returns the location of the uniform variable \a name within this shader + program's parameter list. Returns -1 if \a name is not a valid + uniform variable for this shader program. + + \sa attributeLocation() +*/ +int QGLShaderProgram::uniformLocation(const char *name) const +{ + if (d->linked) { + return glGetUniformLocation(d->program, name); + } else { + qWarning() << "QGLShaderProgram::uniformLocation(" << name + << "): shader program is not linked"; + return -1; + } +} + +/*! + \overload + + Returns the location of the uniform variable \a name within this shader + program's parameter list. Returns -1 if \a name is not a valid + uniform variable for this shader program. + + \sa attributeLocation() +*/ +int QGLShaderProgram::uniformLocation(const QByteArray& name) const +{ + return uniformLocation(name.constData()); +} + +/*! + \overload + + Returns the location of the uniform variable \a name within this shader + program's parameter list. Returns -1 if \a name is not a valid + uniform variable for this shader program. + + \sa attributeLocation() +*/ +int QGLShaderProgram::uniformLocation(const QString& name) const +{ + return uniformLocation(name.toLatin1().constData()); +} + +/*! + Sets the uniform variable at \a location in the current context to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, GLfloat value) +{ + if (location != -1) + glUniform1fv(location, 1, &value); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, GLfloat value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context to \a value. + This function must be used when setting sampler values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, GLint value) +{ + if (location != -1) + glUniform1i(location, value); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to \a value. This function must be used when setting sampler values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, GLint value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context to + the 2D vector (\a x, \a y). + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y) +{ + if (location != -1) { + GLfloat values[2] = {x, y}; + glUniform2fv(location, 1, values); + } +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context to + the 2D vector (\a x, \a y). + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, GLfloat x, GLfloat y) +{ + setUniformValue(uniformLocation(name), x, y); +} + +/*! + Sets the uniform variable at \a location in the current context to + the 3D vector (\a x, \a y, \a z). + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue + (int location, GLfloat x, GLfloat y, GLfloat z) +{ + if (location != -1) { + GLfloat values[3] = {x, y, z}; + glUniform3fv(location, 1, values); + } +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context to + the 3D vector (\a x, \a y, \a z). + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue + (const char *name, GLfloat x, GLfloat y, GLfloat z) +{ + setUniformValue(uniformLocation(name), x, y, z); +} + +/*! + Sets the uniform variable at \a location in the current context to + the 4D vector (\a x, \a y, \a z, \a w). + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue + (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + if (location != -1) { + GLfloat values[4] = {x, y, z, w}; + glUniform4fv(location, 1, values); + } +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context to + the 4D vector (\a x, \a y, \a z, \a w). + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue + (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + setUniformValue(uniformLocation(name), x, y, z, w); +} + +/*! + Sets the uniform variable at \a location in the current context to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QVector2D& value) +{ + if (location != -1) + glUniform2fv(location, 1, reinterpret_cast(&value)); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QVector2D& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QVector3D& value) +{ + if (location != -1) + glUniform3fv(location, 1, reinterpret_cast(&value)); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QVector3D& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QVector4D& value) +{ + if (location != -1) + glUniform4fv(location, 1, reinterpret_cast(&value)); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QVector4D& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context to + the red, green, blue, and alpha components of \a color. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QColor& color) +{ + if (location != -1) { + GLfloat values[4] = {color.redF(), color.greenF(), color.blueF(), color.alphaF()}; + glUniform4fv(location, 1, values); + } +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context to + the red, green, blue, and alpha components of \a color. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QColor& color) +{ + setUniformValue(uniformLocation(name), color); +} + +/*! + Sets the uniform variable at \a location in the current context + to a 2x2 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value) +{ + if (location != -1) + glUniformMatrix2fv(location, 1, GL_FALSE, value.data()); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 2x2 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context + to a 2x3 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value) +{ +#if !defined(QT_OPENGL_ES_2) + if (location != -1) { + if (glUniformMatrix2x3fv) { + // OpenGL 2.1+: pass the matrix directly. + glUniformMatrix2x3fv(location, 1, GL_FALSE, value.data()); + } else { + // OpenGL 2.0: pass the matrix columns as a vector. + glUniform3fv(location, 2, value.data()); + } + } +#else + if (location != -1) + glUniform3fv(location, 2, value.data()); +#endif +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 2x3 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context + to a 2x4 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value) +{ +#if !defined(QT_OPENGL_ES_2) + if (location != -1) { + if (glUniformMatrix2x4fv) { + // OpenGL 2.1+: pass the matrix directly. + glUniformMatrix2x4fv(location, 1, GL_FALSE, value.data()); + } else { + // OpenGL 2.0: pass the matrix columns as a vector. + glUniform4fv(location, 2, value.data()); + } + } +#else + if (location != -1) + glUniform4fv(location, 2, value.data()); +#endif +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 2x4 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context + to a 3x2 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value) +{ +#if !defined(QT_OPENGL_ES_2) + if (location != -1) { + if (glUniformMatrix3x2fv) { + // OpenGL 2.1+: pass the matrix directly. + glUniformMatrix3x2fv(location, 1, GL_FALSE, value.data()); + } else { + // OpenGL 2.0: pass the matrix columns as a vector. + glUniform2fv(location, 3, value.data()); + } + } +#else + if (location != -1) + glUniform2fv(location, 3, value.data()); +#endif +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 3x2 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context + to a 3x3 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value) +{ + if (location != -1) + glUniformMatrix3fv(location, 1, GL_FALSE, value.data()); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 3x3 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context + to a 3x4 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value) +{ +#if !defined(QT_OPENGL_ES_2) + if (location != -1) { + if (glUniformMatrix3x4fv) { + // OpenGL 2.1+: pass the matrix directly. + glUniformMatrix3x4fv(location, 1, GL_FALSE, value.data()); + } else { + // OpenGL 2.0: pass the matrix columns as a vector. + glUniform4fv(location, 3, value.data()); + } + } +#else + if (location != -1) + glUniform4fv(location, 3, value.data()); +#endif +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 3x4 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context + to a 4x2 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value) +{ +#if !defined(QT_OPENGL_ES_2) + if (location != -1) { + if (glUniformMatrix4x2fv) { + // OpenGL 2.1+: pass the matrix directly. + glUniformMatrix4x2fv(location, 1, GL_FALSE, value.data()); + } else { + // OpenGL 2.0: pass the matrix columns as a vector. + glUniform2fv(location, 4, value.data()); + } + } +#else + if (location != -1) + glUniform2fv(location, 4, value.data()); +#endif +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 4x2 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context + to a 4x3 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value) +{ +#if !defined(QT_OPENGL_ES_2) + if (location != -1) { + if (glUniformMatrix4x3fv) { + // OpenGL 2.1+: pass the matrix directly. + glUniformMatrix4x3fv(location, 1, GL_FALSE, value.data()); + } else { + // OpenGL 2.0: pass the matrix columns as a vector. + glUniform3fv(location, 4, value.data()); + } + } +#else + if (location != -1) + glUniform3fv(location, 4, value.data()); +#endif +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 4x3 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context + to a 4x4 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value) +{ + if (location != -1) + glUniformMatrix4fv(location, 1, GL_FALSE, value.data()); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 4x4 matrix \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + \overload + + Sets the uniform variable at \a location in the current context + to a 4x4 matrix \a value. The matrix elements must be specified + in column-major order. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4]) +{ + if (location != -1) + glUniformMatrix4fv(location, 1, GL_FALSE, value[0]); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to a 4x4 matrix \a value. The matrix elements must be specified + in column-major order. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[4][4]) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable at \a location in the current context to a + 3x3 transformation matrix \a value that is specified as a QTransform value. + + To set a QTransform value as a 4x4 matrix in a shader, use + \c{setUniformValue(location, QMatrix4x4(value))}. +*/ +void QGLShaderProgram::setUniformValue(int location, const QTransform& value) +{ + if (location != -1) { + GLfloat mat[3][3] = { + {value.m11(), value.m12(), value.m13()}, + {value.m21(), value.m22(), value.m23()}, + {value.m31(), value.m32(), value.m33()} + }; + glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]); + } +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context to a + 3x3 transformation matrix \a value that is specified as a QTransform value. + + To set a QTransform value as a 4x4 matrix in a shader, use + \c{setUniformValue(name, QMatrix4x4(value))}. +*/ +void QGLShaderProgram::setUniformValue + (const char *name, const QTransform& value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count elements of \a values. This overload + must be used when setting an array of sampler values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count) +{ + if (location != -1) + glUniform1iv(location, count, values); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count elements of \a values. This overload + must be used when setting an array of sampler values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray + (const char *name, const GLint *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count elements of \a values. Each element + has \a size components. The \a size must be 1, 2, 3, or 4. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int size) +{ + if (location != -1) { + if (size == 1) + glUniform1fv(location, count, values); + else if (size == 2) + glUniform2fv(location, count, values); + else if (size == 3) + glUniform3fv(location, count, values); + else if (size == 4) + glUniform4fv(location, count, values); + else + qWarning() << "QGLShaderProgram::setUniformValue: size" << size << "not supported"; + } +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count elements of \a values. Each element + has \a size components. The \a size must be 1, 2, 3, or 4. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray + (const char *name, const GLfloat *values, int count, int size) +{ + setUniformValueArray(uniformLocation(name), values, count, size); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 2D vector elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count) +{ + if (location != -1) + glUniform2fv(location, count, reinterpret_cast(values)); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 2D vector elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QVector2D *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 3D vector elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count) +{ + if (location != -1) + glUniform3fv(location, count, reinterpret_cast(values)); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 3D vector elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QVector3D *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 4D vector elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count) +{ + if (location != -1) + glUniform4fv(location, count, reinterpret_cast(values)); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 4D vector elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +// We may have to repack matrix arrays if the matrix types +// contain additional flag bits. Especially QMatrix4x4. +#define setUniformMatrixArray(func,location,values,count,type,cols,rows) \ + if (location == -1 || count <= 0) \ + return; \ + if (count == 1 || sizeof(type) == cols * rows * sizeof(GLfloat)) { \ + func(location, count, GL_FALSE, values->constData()); \ + } else { \ + QVarLengthArray temp(cols * rows * count); \ + for (int index = 0; index < count; ++index) { \ + qMemCopy(temp.data() + cols * rows * index, \ + values[index].constData(), cols * rows * sizeof(GLfloat)); \ + } \ + func(location, count, GL_FALSE, temp.constData()); \ + } +#if !defined(QT_OPENGL_ES_2) +#define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \ + if (location == -1 || count <= 0) \ + return; \ + if (count == 1 || sizeof(type) == cols * rows * sizeof(GLfloat)) { \ + if (func) \ + func(location, count, GL_FALSE, values->constData()); \ + else \ + colfunc(location, cols * count, values->constData()); \ + } else { \ + QVarLengthArray temp(cols * rows * count); \ + for (int index = 0; index < count; ++index) { \ + qMemCopy(temp.data() + cols * rows * index, \ + values[index].constData(), cols * rows * sizeof(GLfloat)); \ + } \ + if (func) \ + func(location, count, GL_FALSE, temp.constData()); \ + else \ + colfunc(location, count * cols, temp.constData()); \ + } +#else +#define setUniformGenericMatrixArray(func,colfunc,location,values,count,type,cols,rows) \ + if (location == -1 || count <= 0) \ + return; \ + if (count == 1 || sizeof(type) == cols * rows * sizeof(GLfloat)) { \ + colfunc(location, cols * count, values->constData()); \ + } else { \ + QVarLengthArray temp(cols * rows * count); \ + for (int index = 0; index < count; ++index) { \ + qMemCopy(temp.data() + cols * rows * index, \ + values[index].constData(), cols * rows * sizeof(GLfloat)); \ + } \ + colfunc(location, count * cols, temp.constData()); \ + } +#endif + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 2x2 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count) +{ + setUniformMatrixArray + (glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 2x2 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x2 *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 2x3 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count) +{ + setUniformGenericMatrixArray + (glUniformMatrix2x3fv, glUniform3fv, location, values, count, + QMatrix2x3, 2, 3); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 2x3 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x3 *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 2x4 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count) +{ + setUniformGenericMatrixArray + (glUniformMatrix2x4fv, glUniform4fv, location, values, count, + QMatrix2x4, 2, 4); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 2x4 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x4 *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 3x2 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count) +{ + setUniformGenericMatrixArray + (glUniformMatrix3x2fv, glUniform2fv, location, values, count, + QMatrix3x2, 3, 2); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 3x2 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x2 *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 3x3 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count) +{ + setUniformMatrixArray + (glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 3x3 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x3 *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 3x4 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count) +{ + setUniformGenericMatrixArray + (glUniformMatrix3x4fv, glUniform4fv, location, values, count, + QMatrix3x4, 3, 4); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 3x4 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x4 *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 4x2 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count) +{ + setUniformGenericMatrixArray + (glUniformMatrix4x2fv, glUniform2fv, location, values, count, + QMatrix4x2, 4, 2); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 4x2 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x2 *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 4x3 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count) +{ + setUniformGenericMatrixArray + (glUniformMatrix4x3fv, glUniform3fv, location, values, count, + QMatrix4x3, 4, 3); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 4x3 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x3 *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Sets the uniform variable array at \a location in the current + context to the \a count 4x4 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count) +{ + setUniformMatrixArray + (glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4); +} + +/*! + \overload + + Sets the uniform variable array called \a name in the current + context to the \a count 4x4 matrix elements of \a values. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 *values, int count) +{ + setUniformValueArray(uniformLocation(name), values, count); +} + +/*! + Returns true if shader programs written in the OpenGL Shading + Language (GLSL) are supported on this system; false otherwise. + + The \a context is used to resolve the GLSL extensions. + If \a context is null, then QGLContext::currentContext() is used. +*/ +bool QGLShaderProgram::hasShaderPrograms(const QGLContext *context) +{ +#if !defined(QT_OPENGL_ES_2) + if (!context) + context = QGLContext::currentContext(); + if (!context) + return false; + return qt_resolve_glsl_extensions(const_cast(context)); +#else + Q_UNUSED(context); + return true; +#endif +} + +#endif + +QT_END_NAMESPACE diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h new file mode 100644 index 0000000..ec6faaf --- /dev/null +++ b/src/opengl/qglshaderprogram.h @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGLSHADERPROGRAM_H +#define QGLSHADERPROGRAM_H + +#include +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(OpenGL) + +#if !defined(QT_OPENGL_ES_1_CL) && !defined(QT_GL_FIXED_PREFERRED) + +class QGLShaderProgram; +class QGLShaderPrivate; + +class Q_OPENGL_EXPORT QGLShader : public QObject +{ + Q_OBJECT +public: + enum ShaderType + { + VertexShader, + FragmentShader, + PartialVertexShader, + PartialFragmentShader + }; + + explicit QGLShader(QGLShader::ShaderType type, QObject *parent = 0); + explicit QGLShader(const QString& fileName, QObject *parent = 0); + QGLShader(const QString& fileName, QGLShader::ShaderType type, QObject *parent = 0); + QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent = 0); + QGLShader(const QString& fileName, const QGLContext *context, QObject *parent = 0); + QGLShader(const QString& fileName, QGLShader::ShaderType type, const QGLContext *context, QObject *parent = 0); + virtual ~QGLShader(); + + bool isValid() const; + + QGLShader::ShaderType shaderType() const; + + bool setSourceCode(const char *source); + bool setSourceCode(const QByteArray& source); + bool setSourceCode(const QString& source); + bool setSourceCodeFile(const QString& fileName); + + bool setBinaryCode(GLenum format, const void *binary, int length); + bool setBinaryCode(QGLShader& otherShader, GLenum format, const void *binary, int length); + + static QList shaderBinaryFormats(); + + QByteArray sourceCode() const; + + bool isCompiled() const; + QString errors() const; + + GLuint shaderId() const; + +private: + QGLShaderPrivate *d; + + friend class QGLShaderProgram; + + Q_DISABLE_COPY(QGLShader); +}; + +class QGLShaderProgramPrivate; + +class Q_OPENGL_EXPORT QGLShaderProgram : public QObject +{ + Q_OBJECT +public: + explicit QGLShaderProgram(QObject *parent = 0); + explicit QGLShaderProgram(const QGLContext *context, QObject *parent = 0); + virtual ~QGLShaderProgram(); + + bool isValid() const; + + bool addShader(QGLShader *shader); + void removeShader(QGLShader *shader); + QList shaders() const; + + bool addShader(QGLShader::ShaderType type, const char *source); + bool addShader(QGLShader::ShaderType type, const QByteArray& source); + bool addShader(QGLShader::ShaderType type, const QString& source); + + void removeAllShaders(); + + QByteArray programBinary(int *format) const; + bool setProgramBinary(int format, const QByteArray& binary); + static QList programBinaryFormats(); + + virtual bool link(); + bool isLinked() const; + QString errors() const; + + bool enable(); + void disable(); + + GLuint programId() const; + + void bindAttributeLocation(const char *name, int location); + void bindAttributeLocation(const QByteArray& name, int location); + void bindAttributeLocation(const QString& name, int location); + + int attributeLocation(const char *name) const; + int attributeLocation(const QByteArray& name) const; + int attributeLocation(const QString& name) const; + + void setAttributeValue(int location, GLfloat value); + void setAttributeValue(int location, GLfloat x, GLfloat y); + void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z); + void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void setAttributeValue(int location, const QVector2D& value); + void setAttributeValue(int location, const QVector3D& value); + void setAttributeValue(int location, const QVector4D& value); + void setAttributeValue(int location, const QColor& value); + void setAttributeValue(int location, const GLfloat *values, int columns, int rows); + + void setAttributeValue(const char *name, GLfloat value); + void setAttributeValue(const char *name, GLfloat x, GLfloat y); + void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z); + void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void setAttributeValue(const char *name, const QVector2D& value); + void setAttributeValue(const char *name, const QVector3D& value); + void setAttributeValue(const char *name, const QVector4D& value); + void setAttributeValue(const char *name, const QColor& value); + void setAttributeValue(const char *name, const GLfloat *values, int columns, int rows); + + void setAttributeArray + (int location, const GLfloat *values, int size, int stride = 0); + void setAttributeArray + (int location, const QVector2D *values, int stride = 0); + void setAttributeArray + (int location, const QVector3D *values, int stride = 0); + void setAttributeArray + (int location, const QVector4D *values, int stride = 0); + void setAttributeArray + (const char *name, const GLfloat *values, int size, int stride = 0); + void setAttributeArray + (const char *name, const QVector2D *values, int stride = 0); + void setAttributeArray + (const char *name, const QVector3D *values, int stride = 0); + void setAttributeArray + (const char *name, const QVector4D *values, int stride = 0); + void disableAttributeArray(int location); + void disableAttributeArray(const char *name); + + int uniformLocation(const char *name) const; + int uniformLocation(const QByteArray& name) const; + int uniformLocation(const QString& name) const; + + void setUniformValue(int location, GLfloat value); + void setUniformValue(int location, GLint value); + void setUniformValue(int location, GLfloat x, GLfloat y); + void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z); + void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void setUniformValue(int location, const QVector2D& value); + void setUniformValue(int location, const QVector3D& value); + void setUniformValue(int location, const QVector4D& value); + void setUniformValue(int location, const QColor& color); + void setUniformValue(int location, const QMatrix2x2& value); + void setUniformValue(int location, const QMatrix2x3& value); + void setUniformValue(int location, const QMatrix2x4& value); + void setUniformValue(int location, const QMatrix3x2& value); + void setUniformValue(int location, const QMatrix3x3& value); + void setUniformValue(int location, const QMatrix3x4& value); + void setUniformValue(int location, const QMatrix4x2& value); + void setUniformValue(int location, const QMatrix4x3& value); + void setUniformValue(int location, const QMatrix4x4& value); + void setUniformValue(int location, const GLfloat value[4][4]); + void setUniformValue(int location, const QTransform& value); + + void setUniformValue(const char *name, GLfloat value); + void setUniformValue(const char *name, GLint value); + void setUniformValue(const char *name, GLfloat x, GLfloat y); + void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z); + void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void setUniformValue(const char *name, const QVector2D& value); + void setUniformValue(const char *name, const QVector3D& value); + void setUniformValue(const char *name, const QVector4D& value); + void setUniformValue(const char *name, const QColor& color); + void setUniformValue(const char *name, const QMatrix2x2& value); + void setUniformValue(const char *name, const QMatrix2x3& value); + void setUniformValue(const char *name, const QMatrix2x4& value); + void setUniformValue(const char *name, const QMatrix3x2& value); + void setUniformValue(const char *name, const QMatrix3x3& value); + void setUniformValue(const char *name, const QMatrix3x4& value); + void setUniformValue(const char *name, const QMatrix4x2& value); + void setUniformValue(const char *name, const QMatrix4x3& value); + void setUniformValue(const char *name, const QMatrix4x4& value); + void setUniformValue(const char *name, const GLfloat value[4][4]); + void setUniformValue(const char *name, const QTransform& value); + + void setUniformValueArray(int location, const GLfloat *values, int count, int size); + void setUniformValueArray(int location, const GLint *values, int count); + void setUniformValueArray(int location, const QVector2D *values, int count); + void setUniformValueArray(int location, const QVector3D *values, int count); + void setUniformValueArray(int location, const QVector4D *values, int count); + void setUniformValueArray(int location, const QMatrix2x2 *values, int count); + void setUniformValueArray(int location, const QMatrix2x3 *values, int count); + void setUniformValueArray(int location, const QMatrix2x4 *values, int count); + void setUniformValueArray(int location, const QMatrix3x2 *values, int count); + void setUniformValueArray(int location, const QMatrix3x3 *values, int count); + void setUniformValueArray(int location, const QMatrix3x4 *values, int count); + void setUniformValueArray(int location, const QMatrix4x2 *values, int count); + void setUniformValueArray(int location, const QMatrix4x3 *values, int count); + void setUniformValueArray(int location, const QMatrix4x4 *values, int count); + + void setUniformValueArray(const char *name, const GLfloat *values, int count, int size); + void setUniformValueArray(const char *name, const GLint *values, int count); + void setUniformValueArray(const char *name, const QVector2D *values, int count); + void setUniformValueArray(const char *name, const QVector3D *values, int count); + void setUniformValueArray(const char *name, const QVector4D *values, int count); + void setUniformValueArray(const char *name, const QMatrix2x2 *values, int count); + void setUniformValueArray(const char *name, const QMatrix2x3 *values, int count); + void setUniformValueArray(const char *name, const QMatrix2x4 *values, int count); + void setUniformValueArray(const char *name, const QMatrix3x2 *values, int count); + void setUniformValueArray(const char *name, const QMatrix3x3 *values, int count); + void setUniformValueArray(const char *name, const QMatrix3x4 *values, int count); + void setUniformValueArray(const char *name, const QMatrix4x2 *values, int count); + void setUniformValueArray(const char *name, const QMatrix4x3 *values, int count); + void setUniformValueArray(const char *name, const QMatrix4x4 *values, int count); + + static bool hasShaderPrograms(const QGLContext *context = 0); + +private: + QGLShaderProgramPrivate *d; + + Q_DISABLE_COPY(QGLShaderProgram); + + bool init(); +}; + +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif -- cgit v0.12 From 0b97a00eae721304a31642fcb8892b66fb670f9e Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 27 Mar 2009 12:22:04 +1000 Subject: Bug in QGLShaderProgram::addShader() that stopped partial shaders working. --- src/opengl/qglshaderprogram.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 934b5a5..3c19434 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -849,13 +849,16 @@ bool QGLShaderProgram::addShader(QGLShader *shader) return false; if (d->shaders.contains(shader)) return true; // Already added to this shader program. - if (d->program && shader && shader->d->shader) { + if (d->program && shader) { if (!shader->d->compiled) return false; - if (!shader->d->isPartial) + if (!shader->d->isPartial) { + if (!shader->d->shader) + return false; glAttachShader(d->program, shader->d->shader); - else + } else { d->hasPartialShaders = true; + } d->linked = false; // Program needs to be relinked. d->shaders.append(shader); return true; -- cgit v0.12 From 0cbe2a23966116e642fee4ccc34aeac73a5c57cd Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 27 Mar 2009 12:34:48 +1000 Subject: Fix loading of partial shaders from files. --- src/opengl/qglshaderprogram.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 3c19434..5738acd 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -573,9 +573,6 @@ bool QGLShader::setSourceCode(const QString& source) */ bool QGLShader::setSourceCodeFile(const QString& fileName) { - if (!d->shader) - return false; - QFile file(fileName); if (!file.open(QFile::ReadOnly)) { qWarning() << "QGLShader: Unable to open file" << fileName; -- cgit v0.12 From 8559f2d8db6f99292fc8a26623e166f64f9d4a8f Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 3 Apr 2009 12:59:10 +0200 Subject: Fix build breakage after rebasing on graphics-main Reviewed-by: Trustme --- src/opengl/gl2paintengineex/qglshader.cpp | 1 + src/opengl/qglextensions_p.h | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglshader.cpp b/src/opengl/gl2paintengineex/qglshader.cpp index 4ac6e61..ea4cae9 100644 --- a/src/opengl/gl2paintengineex/qglshader.cpp +++ b/src/opengl/gl2paintengineex/qglshader.cpp @@ -51,6 +51,7 @@ #if !defined(QT_OPENGL_ES_2) static const char *qglslDefines = "#define lowp\n#define mediump\n#define highp\n"; +#include "private/qgl_p.h" #else static const char *qglslDefines = ""; #endif diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 69632e7..9249730 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -412,18 +412,10 @@ struct QGLExtensionFuncs _glUnmapBufferARB qt_glUnmapBufferARB; _glGetActiveAttrib qt_glGetActiveAttrib; - _glGetAttribLocation qt_glGetAttribLocation; _glGetActiveUniform qt_glGetActiveUniform; - _glGetProgramInfoLog qt_glGetProgramInfoLog; _glUniform1f qt_glUniform1f; _glUniform2f qt_glUniform2f; _glUniform4f qt_glUniform4f; - _glUniformMatrix2fv qt_glUniformMatrix2fv; - _glUniformMatrix3fv qt_glUniformMatrix3fv; - _glUniformMatrix4fv qt_glUniformMatrix4fv; - _glEnableVertexAttribArray qt_glEnableVertexAttribArray; - _glDisableVertexAttribArray qt_glDisableVertexAttribArray; - _glVertexAttribPointer qt_glVertexAttribPointer; _glStencilOpSeparate qt_glStencilOpSeparate; }; -- cgit v0.12 From 2485575f1883fe990d0072eed2231a5bd06948af Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 3 Apr 2009 14:30:25 +0200 Subject: Add (big) comment explaining shader pipeline in GL2 engine Reviewed-by: TrustMe --- src/opengl/gl2paintengineex/glgc_shader_source.h | 138 +++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/src/opengl/gl2paintengineex/glgc_shader_source.h b/src/opengl/gl2paintengineex/glgc_shader_source.h index 5b9d28b..47a1cbb 100644 --- a/src/opengl/gl2paintengineex/glgc_shader_source.h +++ b/src/opengl/gl2paintengineex/glgc_shader_source.h @@ -48,6 +48,144 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) + +/* + VERTEX SHADERS + ============== + + Vertex shaders are specified as multiple (partial) shaders. On desktop, + this works fine. On ES, QGLShader & QGLShaderProgram will make partial + shaders work by concatenating the source in each QGLShader and compiling + it as a single shader. This is abstracted nicely by QGLShaderProgram and + the GL2 engine doesn't need to worry about it. + + Generally, there's two vertex shader objects. The position shaders are + the ones which set gl_Position. There's also two "main" vertex shaders, + one which just calls the position shader and another which also passes + through some texture coordinates from a vertex attribute array to a + varying. These texture coordinates are used for mask position in text + rendering and for the source coordinates in drawImage/drawPixmap. There's + also a "Simple" vertex shader for rendering a solid colour (used to render + into the stencil buffer where the actual colour value is discarded). + + The position shaders for brushes look scary. This is because many of the + calculations which logically belong in the fragment shader have been moved + into the vertex shader to improve performance. This is why the position + calculation is in a seperate shader. Not only does it calculate the + position, but it also calculates some data to be passed to the fragment + shader as a varying. It is optimal to move as much of the calculation as + possible into the vertex shader as this is executed less often. + + The varyings passed to the fragment shaders are interpolated (which is + cheap). Unfortunately, GL will apply perspective correction to the + interpolation calusing errors. To get around this, the vertex shader must + apply perspective correction itself and set the w-value of gl_Position to + zero. That way, GL will be tricked into thinking it doesn't need to apply a + perspective correction and use linear interpolation instead (which is what + we want). Of course, if the brush transform is affeine, no perspective + correction is needed and a simpler vertex shader can be used instead. + + So there are the following "main" vertex shaders: + qglslSimpleVertexShader + qglslMainVertexShader + qglslMainWithTexCoordsVertexShader + + And the the following position vertex shaders: + qglslPositionOnlyVertexShader + qglslPositionWithTextureBrushVertexShader + qglslPositionWithPatternBrushVertexShader + qglslPositionWithLinearGradientBrushVertexShader + qglslPositionWithRadialGradientBrushVertexShader + qglslPositionWithConicalGradientBrushVertexShader + qglslAffinePositionWithTextureBrushVertexShader + qglslAffinePositionWithPatternBrushVertexShader + qglslAffinePositionWithLinearGradientBrushVertexShader + qglslAffinePositionWithRadialGradientBrushVertexShader + qglslAffinePositionWithConicalGradientBrushVertexShader + + Leading to 23 possible vertex shaders + + + FRAGMENT SHADERS + ================ + + Fragment shaders are also specified as multiple (partial) shaders. The + different fragment shaders represent the different stages in Qt's fragment + pipeline. There are 1-3 stages in this pipeline: First stage is to get the + fragment's colour value. The next stage is to get the fragment's mask value + (coverage value for anti-aliasing) and the final stage is to blend the + incoming fragment with the background (for composition modes not supported + by GL). + + Of these, the first stage will always be present. If Qt doesn't need to + apply anti-aliasing (because it's off or handled by multisampling) then + the coverage value doesn't need to be applied. (Note: There are two types + of mask, one for regular anti-aliasing and one for sub-pixel anti- + aliasing.) If the composition mode is one which GL supports natively then + the blending stage doesn't need to be applied. + + As eash stage can have multiple implementations, they are abstracted as + GLSL function calls, with the following signatures: + + Brushes & image drawing are implementations of "mediump vec4 srcPixel()": + qglslImageFragmentShader + qglslNonPremultipliedImageFragmentShader + qglslSolidBrushFragmentShader + qglslTextureBrushFragmentShader + qglslPatternBrushFragmentShader + qglslLinearGradientBrushFragmentShader + qglslRadialGradientBrushFragmentShader + qglslConicalGradientBrushFragmentShader + + NOTE: It is assumed the colour returned by srcPixel() is pre-multiplied + + The two masks are have these signature and are called: + qglslMaskFragmentShader: "mediump float mask()" + qglslRgbMaskFragmentShader: "mediump vec3 rgbMask()" + + Composition modes are "mediump vec4 composite(mediump vec4 src, mediump vec4 dest)": + qglslColorBurnCompositionModeFragmentShader + qglslColorDodgeCompositionModeFragmentShader + qglslDarkenCompositionModeFragmentShader + qglslDifferenceCompositionModeFragmentShader + qglslExclusionCompositionModeFragmentShader + qglslHardLightCompositionModeFragmentShader + qglslLightenCompositionModeFragmentShader + qglslMultiplyCompositionModeFragmentShader + qglslOverlayCompositionModeFragmentShader + qglslScreenCompositionModeFragmentShader + qglslSoftLightCompositionModeFragmentShader + + + So there are differnt frament shader main functions, depending on the + number & type of pipelines the fragment needs to go through. + + The choice of which main() fragment shader string to use depends on: + - Use of global opacity + - Brush style (some brushes apply opacity themselves) + - Use & type of mask (TODO: Need to support high quality anti-aliasing & text) + - Use of gamma-correction + - Use of non-GL Composition mode + + + CUSTOM SHADER CODE (idea) + ================== + + The use of custom shader code is supported by the engine for drawImage and + drawPixmap calls. This is implemented via hooks in the fragment pipeline. + The custom shader is passed to the engine as a partial fragment shader + (QGLCustomizedShader). The shader will implement a pre-defined method name + which Qt's fragment pipeline will call. There are two different hooks which + can be implemented as custom shader code: + + mediump vec4 customShader(sampler2d src, vec2 srcCoords) + mediump vec4 customShaderWithDest(sampler2d dest, sampler2d src, vec2 srcCoords) + +*/ + +///////////////////////////////////////////////////////////////////// + + static const char* qglslImageVertexShader = "\ attribute highp vec4 inputVertex; \ attribute lowp vec2 textureCoord; \ -- cgit v0.12 From fbce782f1d566c318737bf7e5ab55d0a66fb2a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 16 Apr 2009 10:37:08 +0200 Subject: Fix off-by-one bugs in the framebuffer blits. The bottom-right coordinates are exclusive, not inclusive. --- src/opengl/qglframebufferobject.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 45d4788..61d0f85 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -1132,14 +1132,14 @@ void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const Q const int th = target ? target->height() : height; const int sx0 = sourceRect.left(); - const int sx1 = sourceRect.right(); - const int sy0 = sh - sourceRect.bottom() - 1; - const int sy1 = sh - sourceRect.top() - 1; + const int sx1 = sourceRect.left() + sourceRect.width(); + const int sy0 = sh - (sourceRect.top() + sourceRect.height()); + const int sy1 = sh - sourceRect.top(); const int tx0 = targetRect.left(); - const int tx1 = targetRect.right(); - const int ty0 = th - targetRect.bottom() - 1; - const int ty1 = th - targetRect.top() - 1; + const int tx1 = targetRect.left() + targetRect.width(); + const int ty0 = th - (targetRect.top() + targetRect.height()); + const int ty1 = th - targetRect.top(); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source ? source->handle() : 0); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, target ? target->handle() : 0); -- cgit v0.12 From d4eb0a29e73eb1f6c7e2909e6ae0302605927e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 24 Mar 2009 15:10:01 +0100 Subject: GL2: Avoid expensive updateDepthClip() every time setState() is called Only call updateDepthClip() if the clip has actually changed. --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 30 ++++++++++------------ .../gl2paintengineex/qpaintengineex_opengl2_p.h | 1 - 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 89ed1f7..e166b54 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1200,11 +1200,6 @@ void QGL2PaintEngineEx::updateClipRegion(const QRegion &clipRegion, Qt::ClipOper state()->hasClipping = op != Qt::NoClip || d->use_system_clip; } - if (state()->hasClipping && state()->clipRegion.rects().size() == 1) - state()->fastClip = state()->clipRegion.rects().at(0); - else - state()->fastClip = QRect(); - d->updateDepthClip(); } @@ -1221,14 +1216,10 @@ void QGL2PaintEngineExPrivate::updateDepthClip() if (!q->state()->hasClipping) return; - QRect fastClip; - if (q->state()->clipEnabled) { - fastClip = q->state()->fastClip; - } else if (use_system_clip && q->systemClip().rects().count() == 1) { - fastClip = q->systemClip().rects().at(0); - } + const QVector rects = q->state()->clipEnabled ? q->state()->clipRegion.rects() : q->systemClip().rects(); + if (rects.size() == 1) { + QRect fastClip = rects.at(0); - if (!fastClip.isEmpty()) { glEnable(GL_SCISSOR_TEST); const int left = fastClip.left(); @@ -1245,7 +1236,6 @@ void QGL2PaintEngineExPrivate::updateDepthClip() glClear(GL_DEPTH_BUFFER_BIT); glClearDepthf(0x1); - const QVector rects = q->state()->clipEnabled ? q->state()->clipRegion.rects() : q->systemClip().rects(); glEnable(GL_SCISSOR_TEST); for (int i = 0; i < rects.size(); ++i) { QRect rect = rects.at(i); @@ -1268,14 +1258,23 @@ void QGL2PaintEngineExPrivate::updateDepthClip() -void QGL2PaintEngineEx::setState(QPainterState *s) +void QGL2PaintEngineEx::setState(QPainterState *new_state) { // qDebug("QGL2PaintEngineEx::setState()"); Q_D(QGL2PaintEngineEx); + + QOpenGLPaintEngineState *s = static_cast(new_state); + + QOpenGLPaintEngineState *old_state = state(); + const bool needsDepthClipUpdate = !old_state + || s->clipEnabled != old_state->clipEnabled + || s->clipEnabled && s->clipRegion != old_state->clipRegion; + QPaintEngineEx::setState(s); - d->updateDepthClip(); + if (needsDepthClipUpdate) + d->updateDepthClip(); d->matrixDirty = true; d->compositionModeDirty = true; @@ -1303,7 +1302,6 @@ QOpenGLPaintEngineState::QOpenGLPaintEngineState(QOpenGLPaintEngineState &other) { clipRegion = other.clipRegion; hasClipping = other.hasClipping; - fastClip = other.fastClip; } QOpenGLPaintEngineState::QOpenGLPaintEngineState() diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 9f84a25..10e5337 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -67,7 +67,6 @@ public: QRegion clipRegion; bool hasClipping; - QRect fastClip; }; -- cgit v0.12 From b1c0c0bf169d4ab83ce6e9b1b333e99610aa6f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 26 Mar 2009 10:14:07 +0100 Subject: Ensure we don't access the GL share widget when it's being destroyed. Zero the pointer before destroying the widget, as QGLWidget's destructor may indirectly trigger access to the share widget. --- src/opengl/qwindowsurface_gl.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index b4a4565..bed08cf 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -187,9 +187,10 @@ public: } void cleanup() { - delete widget; - widget = 0; + QGLWidget *w = widget; cleanedUp = true; + widget = 0; + delete w; } static bool cleanedUp; -- cgit v0.12 From 1e1371e19ae62a5bf57dcad8d53ac70dcd2ad0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 19 Mar 2009 10:07:26 +0100 Subject: Make FBO the default instead of pixel buffers in GL window surface. Fall back to using pbuffers only if the FBO fails. --- src/opengl/qwindowsurface_gl.cpp | 57 ++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index bed08cf..c9d23d1 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -493,6 +493,35 @@ void QGLWindowSurface::updateGeometry() return; } + if ((QGLExtensions::glExtensions & QGLExtensions::FramebufferObject) && (d_ptr->fbo || !d_ptr->tried_fbo)) { + d_ptr->tried_fbo = true; + hijackWindow(window()); + QGLContext *ctx = reinterpret_cast(window()->d_func()->extraData()->glContext); + ctx->d_ptr->internal_context = true; + ctx->makeCurrent(); + delete d_ptr->fbo; + + QGLFramebufferObjectFormat format; + format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); + format.setInternalFormat(GL_RGBA); + format.setTextureTarget(target); + + if (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) + format.setSamples(8); + + d_ptr->fbo = new QGLFramebufferObject(rect.size(), format); + d_ptr->fbo->bind(); + if (d_ptr->fbo->isValid()) { + qDebug() << "Created Window Surface FBO" << rect.size() + << "with samples" << d_ptr->fbo->format().samples(); + return; + } else { + qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back"; + delete d_ptr->fbo; + d_ptr->fbo = 0; + } + } + if (d_ptr->pb || !d_ptr->tried_pb) { d_ptr->tried_pb = true; @@ -536,34 +565,6 @@ void QGLWindowSurface::updateGeometry() } } - if ((QGLExtensions::glExtensions & QGLExtensions::FramebufferObject) && (d_ptr->fbo || !d_ptr->tried_fbo)) { - d_ptr->tried_fbo = true; - hijackWindow(window()); - QGLContext *ctx = reinterpret_cast(window()->d_func()->extraData()->glContext); - ctx->d_ptr->internal_context = true; - ctx->makeCurrent(); - delete d_ptr->fbo; - - QGLFramebufferObjectFormat format; - format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - format.setInternalFormat(GL_RGBA); - format.setTextureTarget(target); - - if (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) - format.setSamples(8); - - d_ptr->fbo = new QGLFramebufferObject(rect.size(), format); - d_ptr->fbo->bind(); - if (d_ptr->fbo->isValid()) { - qDebug() << "Created Window Surface FBO" << rect.size() - << "with samples" << d_ptr->fbo->format().samples(); - return; - } else { - qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back"; - delete d_ptr->fbo; - d_ptr->fbo = 0; - } - } hijackWindow(window()); QGLContext *ctx = reinterpret_cast(window()->d_func()->extraData()->glContext); -- cgit v0.12 From 99a790fe26f8217783edd1ee05937100dc7536cc Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 15 Apr 2009 14:48:11 +0200 Subject: Add uniform setters for Qt data types to QGLShaderProgram Reviewed-by: Rhys Weatherley --- src/opengl/qglshaderprogram.cpp | 132 ++++++++++++++++++++++++++++++++++++++++ src/opengl/qglshaderprogram.h | 10 +++ 2 files changed, 142 insertions(+) diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 5738acd..c2be1be 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -1836,6 +1836,30 @@ void QGLShaderProgram::setUniformValue(const char *name, GLint value) } /*! + Sets the uniform variable at \a location in the current context to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, GLuint value) +{ + if (location != -1) + glUniform1i(location, value); +} + +/*! + \overload + + Sets the uniform variable called \a name in the current context + to \a value. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, GLuint value) +{ + setUniformValue(uniformLocation(name), value); +} + +/*! Sets the uniform variable at \a location in the current context to the 2D vector (\a x, \a y). @@ -2020,6 +2044,114 @@ void QGLShaderProgram::setUniformValue(const char *name, const QColor& color) } /*! + Sets the uniform variable at \a location in the current context to + the x() & y() coordinates of \a point. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QPoint& point) +{ + if (location != -1) { + GLfloat values[4] = {point.x(), point.y()}; + glUniform2fv(location, 1, values); + } +} + +/*! + \overload + + Sets the uniform variable at \a location in the current context to + the x() & y() coordinates of \a point. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QPoint& point) +{ + setUniformValue(uniformLocation(name), point); +} + +/*! + Sets the uniform variable at \a location in the current context to + the x() & y() coordinates of \a point. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QPointF& point) +{ + if (location != -1) { + GLfloat values[4] = {point.x(), point.y()}; + glUniform2fv(location, 1, values); + } +} + +/*! + \overload + + Sets the uniform variable at \a location in the current context to + the x() & y() coordinates of \a point. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QPointF& point) +{ + setUniformValue(uniformLocation(name), point); +} + +/*! + Sets the uniform variable at \a location in the current context to + the width() & height() of the given \a size. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QSize& size) +{ + if (location != -1) { + GLfloat values[4] = {size.width(), size.width()}; + glUniform2fv(location, 1, values); + } +} + +/*! + \overload + + Sets the uniform variable at \a location in the current context to + the width() & height() of the given \a size. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QSize& size) +{ + setUniformValue(uniformLocation(name), size); +} + +/*! + Sets the uniform variable at \a location in the current context to + the width() & height() of the given \a size. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(int location, const QSizeF& size) +{ + if (location != -1) { + GLfloat values[4] = {size.width(), size.height()}; + glUniform2fv(location, 1, values); + } +} + +/*! + \overload + + Sets the uniform variable at \a location in the current context to + the width() & height() of the given \a size. + + \sa setAttributeValue() +*/ +void QGLShaderProgram::setUniformValue(const char *name, const QSizeF& size) +{ + setUniformValue(uniformLocation(name), size); +} + +/*! Sets the uniform variable at \a location in the current context to a 2x2 matrix \a value. diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h index ec6faaf..508fd96 100644 --- a/src/opengl/qglshaderprogram.h +++ b/src/opengl/qglshaderprogram.h @@ -196,6 +196,7 @@ public: void setUniformValue(int location, GLfloat value); void setUniformValue(int location, GLint value); + void setUniformValue(int location, GLuint value); void setUniformValue(int location, GLfloat x, GLfloat y); void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z); void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); @@ -203,6 +204,10 @@ public: void setUniformValue(int location, const QVector3D& value); void setUniformValue(int location, const QVector4D& value); void setUniformValue(int location, const QColor& color); + void setUniformValue(int location, const QPoint& point); + void setUniformValue(int location, const QPointF& point); + void setUniformValue(int location, const QSize& size); + void setUniformValue(int location, const QSizeF& size); void setUniformValue(int location, const QMatrix2x2& value); void setUniformValue(int location, const QMatrix2x3& value); void setUniformValue(int location, const QMatrix2x4& value); @@ -217,6 +222,7 @@ public: void setUniformValue(const char *name, GLfloat value); void setUniformValue(const char *name, GLint value); + void setUniformValue(const char *name, GLuint value); void setUniformValue(const char *name, GLfloat x, GLfloat y); void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z); void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); @@ -224,6 +230,10 @@ public: void setUniformValue(const char *name, const QVector3D& value); void setUniformValue(const char *name, const QVector4D& value); void setUniformValue(const char *name, const QColor& color); + void setUniformValue(const char *name, const QPoint& point); + void setUniformValue(const char *name, const QPointF& point); + void setUniformValue(const char *name, const QSize& size); + void setUniformValue(const char *name, const QSizeF& size); void setUniformValue(const char *name, const QMatrix2x2& value); void setUniformValue(const char *name, const QMatrix2x3& value); void setUniformValue(const char *name, const QMatrix2x4& value); -- cgit v0.12 From adf67f5ab53758f9661b65a940ec34b4d4db6390 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 15 Apr 2009 13:33:25 +0200 Subject: Re-write the shader manager & completely break everything ;-) --- src/opengl/gl2paintengineex/glgc_shader_source.h | 137 ------- .../gl2paintengineex/qglengineshadermanager.cpp | 367 +++++++++++++++++ .../gl2paintengineex/qglengineshadermanager_p.h | 385 ++++++++++++++++++ .../gl2paintengineex/qglpexshadermanager.cpp | 450 --------------------- .../gl2paintengineex/qglpexshadermanager_p.h | 156 ------- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 4 +- src/opengl/opengl.pro | 9 +- 7 files changed, 758 insertions(+), 750 deletions(-) create mode 100644 src/opengl/gl2paintengineex/qglengineshadermanager.cpp create mode 100644 src/opengl/gl2paintengineex/qglengineshadermanager_p.h delete mode 100644 src/opengl/gl2paintengineex/qglpexshadermanager.cpp delete mode 100644 src/opengl/gl2paintengineex/qglpexshadermanager_p.h diff --git a/src/opengl/gl2paintengineex/glgc_shader_source.h b/src/opengl/gl2paintengineex/glgc_shader_source.h index 47a1cbb..5184c78 100644 --- a/src/opengl/gl2paintengineex/glgc_shader_source.h +++ b/src/opengl/gl2paintengineex/glgc_shader_source.h @@ -49,143 +49,6 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) -/* - VERTEX SHADERS - ============== - - Vertex shaders are specified as multiple (partial) shaders. On desktop, - this works fine. On ES, QGLShader & QGLShaderProgram will make partial - shaders work by concatenating the source in each QGLShader and compiling - it as a single shader. This is abstracted nicely by QGLShaderProgram and - the GL2 engine doesn't need to worry about it. - - Generally, there's two vertex shader objects. The position shaders are - the ones which set gl_Position. There's also two "main" vertex shaders, - one which just calls the position shader and another which also passes - through some texture coordinates from a vertex attribute array to a - varying. These texture coordinates are used for mask position in text - rendering and for the source coordinates in drawImage/drawPixmap. There's - also a "Simple" vertex shader for rendering a solid colour (used to render - into the stencil buffer where the actual colour value is discarded). - - The position shaders for brushes look scary. This is because many of the - calculations which logically belong in the fragment shader have been moved - into the vertex shader to improve performance. This is why the position - calculation is in a seperate shader. Not only does it calculate the - position, but it also calculates some data to be passed to the fragment - shader as a varying. It is optimal to move as much of the calculation as - possible into the vertex shader as this is executed less often. - - The varyings passed to the fragment shaders are interpolated (which is - cheap). Unfortunately, GL will apply perspective correction to the - interpolation calusing errors. To get around this, the vertex shader must - apply perspective correction itself and set the w-value of gl_Position to - zero. That way, GL will be tricked into thinking it doesn't need to apply a - perspective correction and use linear interpolation instead (which is what - we want). Of course, if the brush transform is affeine, no perspective - correction is needed and a simpler vertex shader can be used instead. - - So there are the following "main" vertex shaders: - qglslSimpleVertexShader - qglslMainVertexShader - qglslMainWithTexCoordsVertexShader - - And the the following position vertex shaders: - qglslPositionOnlyVertexShader - qglslPositionWithTextureBrushVertexShader - qglslPositionWithPatternBrushVertexShader - qglslPositionWithLinearGradientBrushVertexShader - qglslPositionWithRadialGradientBrushVertexShader - qglslPositionWithConicalGradientBrushVertexShader - qglslAffinePositionWithTextureBrushVertexShader - qglslAffinePositionWithPatternBrushVertexShader - qglslAffinePositionWithLinearGradientBrushVertexShader - qglslAffinePositionWithRadialGradientBrushVertexShader - qglslAffinePositionWithConicalGradientBrushVertexShader - - Leading to 23 possible vertex shaders - - - FRAGMENT SHADERS - ================ - - Fragment shaders are also specified as multiple (partial) shaders. The - different fragment shaders represent the different stages in Qt's fragment - pipeline. There are 1-3 stages in this pipeline: First stage is to get the - fragment's colour value. The next stage is to get the fragment's mask value - (coverage value for anti-aliasing) and the final stage is to blend the - incoming fragment with the background (for composition modes not supported - by GL). - - Of these, the first stage will always be present. If Qt doesn't need to - apply anti-aliasing (because it's off or handled by multisampling) then - the coverage value doesn't need to be applied. (Note: There are two types - of mask, one for regular anti-aliasing and one for sub-pixel anti- - aliasing.) If the composition mode is one which GL supports natively then - the blending stage doesn't need to be applied. - - As eash stage can have multiple implementations, they are abstracted as - GLSL function calls, with the following signatures: - - Brushes & image drawing are implementations of "mediump vec4 srcPixel()": - qglslImageFragmentShader - qglslNonPremultipliedImageFragmentShader - qglslSolidBrushFragmentShader - qglslTextureBrushFragmentShader - qglslPatternBrushFragmentShader - qglslLinearGradientBrushFragmentShader - qglslRadialGradientBrushFragmentShader - qglslConicalGradientBrushFragmentShader - - NOTE: It is assumed the colour returned by srcPixel() is pre-multiplied - - The two masks are have these signature and are called: - qglslMaskFragmentShader: "mediump float mask()" - qglslRgbMaskFragmentShader: "mediump vec3 rgbMask()" - - Composition modes are "mediump vec4 composite(mediump vec4 src, mediump vec4 dest)": - qglslColorBurnCompositionModeFragmentShader - qglslColorDodgeCompositionModeFragmentShader - qglslDarkenCompositionModeFragmentShader - qglslDifferenceCompositionModeFragmentShader - qglslExclusionCompositionModeFragmentShader - qglslHardLightCompositionModeFragmentShader - qglslLightenCompositionModeFragmentShader - qglslMultiplyCompositionModeFragmentShader - qglslOverlayCompositionModeFragmentShader - qglslScreenCompositionModeFragmentShader - qglslSoftLightCompositionModeFragmentShader - - - So there are differnt frament shader main functions, depending on the - number & type of pipelines the fragment needs to go through. - - The choice of which main() fragment shader string to use depends on: - - Use of global opacity - - Brush style (some brushes apply opacity themselves) - - Use & type of mask (TODO: Need to support high quality anti-aliasing & text) - - Use of gamma-correction - - Use of non-GL Composition mode - - - CUSTOM SHADER CODE (idea) - ================== - - The use of custom shader code is supported by the engine for drawImage and - drawPixmap calls. This is implemented via hooks in the fragment pipeline. - The custom shader is passed to the engine as a partial fragment shader - (QGLCustomizedShader). The shader will implement a pre-defined method name - which Qt's fragment pipeline will call. There are two different hooks which - can be implemented as custom shader code: - - mediump vec4 customShader(sampler2d src, vec2 srcCoords) - mediump vec4 customShaderWithDest(sampler2d dest, sampler2d src, vec2 srcCoords) - -*/ - -///////////////////////////////////////////////////////////////////// - - static const char* qglslImageVertexShader = "\ attribute highp vec4 inputVertex; \ attribute lowp vec2 textureCoord; \ diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp new file mode 100644 index 0000000..1086430 --- /dev/null +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -0,0 +1,367 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qglengineshadermanager_p.h" + +#if defined(QT_DEBUG) +#include +#endif + + +QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) + : ctx(context), + shaderProgNeedsChanging(true), + srcPixelType(Qt::NoBrush), + useGlobalOpacity(false), + maskType(NoMask), + useTextureCoords(false), + compositionMode(QPainter::CompositionMode_SourceOver), + simpleShaderProg(0), + currentShaderProg(0) +{ + memset(compiledShaders, 0, sizeof(compiledShaders)); +} + +QGLEngineShaderManager::~QGLEngineShaderManager() +{ + //### +} + + + + + +void QGLEngineShaderManager::optimiseForBrushTransform(const QTransform transform) +{ + Q_UNUSED(transform); // Currently ignored +} + +void QGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style) +{ + srcPixelType = style; + shaderProgNeedsChanging = true; //### +} + +void QGLEngineShaderManager::setSrcPixelType(PixelSrcType type) +{ + srcPixelType = type; + shaderProgNeedsChanging = true; //### +} + +void QGLEngineShaderManager::setTextureCoordsEnabled(bool enabled) +{ + useTextureCoords = enabled; + shaderProgNeedsChanging = true; //### +} + +void QGLEngineShaderManager::setUseGlobalOpacity(bool useOpacity) +{ + useGlobalOpacity = useOpacity; + shaderProgNeedsChanging = true; //### +} + +void QGLEngineShaderManager::setMaskType(MaskType type) +{ + maskType = type; + shaderProgNeedsChanging = true; //### +} + +void QGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode) +{ + compositionMode = mode; + shaderProgNeedsChanging = true; //### +} + +bool QGLEngineShaderManager::shaderProgramDirty() +{ + return shaderProgNeedsChanging; +} + +QGLShaderProgram* QGLEngineShaderManager::currentProgram() +{ + return currentShaderProg; +} + +QGLShaderProgram* QGLEngineShaderManager::simpleProgram() +{ + return simpleShaderProg; +} + + + + +// Select & use the correct shader program using the current state +void QGLEngineShaderManager::useCorrectShaderProg() +{ + QGLEngineShaderProg requiredProgram; + + // Choose vertex shader main function + QGLEngineShaderManager::ShaderName mainVertexShaderName = InvalidShaderName; + if (useTextureCoords) + mainVertexShaderName = MainWithTexCoordsVertexShader; + else + mainVertexShaderName = MainVertexShader; + compileNamedShader(mainVertexShaderName, QGLShader::PartialVertexShader); + requiredProgram.mainVertexShader = compiledShaders[mainVertexShaderName]; + + // Choose vertex shader shader position function (which typically also sets + // varyings) and the source pixel (srcPixel) fragment shader function: + QGLEngineShaderManager::ShaderName positionVertexShaderName = InvalidShaderName; + QGLEngineShaderManager::ShaderName srcPixelFragShaderName = InvalidShaderName; + bool isAffine = transform.isAffine(); + if ( (srcPixelType >= Qt::Dense1Pattern) && (srcPixelType <= Qt::DiagCrossPattern) ) { + if (isAffine) + positionVertexShaderName = AffinePositionWithPatternBrushVertexShader; + else + positionVertexShaderName = PositionWithPatternBrushVertexShader; + + srcPixelFragShaderName = PatternBrushSrcFragmentShader; + } + else switch (srcPixelType) { + default: + case Qt::NoBrush: + qCritical("QGLEngineShaderManager::useCorrectShaderProg() - I'm scared, Qt::NoBrush style is set"); + break; + case QGLEngineShaderManager::ImageSrc: + srcPixelFragShaderName = ImageSrcFragmentShader; + positionVertexShaderName = PositionOnlyVertexShader; + break; + case QGLEngineShaderManager::NonPremultipliedImageSrc: + srcPixelFragShaderName = NonPremultipliedImageSrcFragmentShader; + positionVertexShaderName = PositionOnlyVertexShader; + break; + case Qt::SolidPattern: + srcPixelFragShaderName = SolidBrushSrcFragmentShader; + positionVertexShaderName = PositionOnlyVertexShader; + break; + case Qt::LinearGradientPattern: + srcPixelFragShaderName = LinearGradientBrushSrcFragmentShader; + positionVertexShaderName = isAffine ? AffinePositionWithLinearGradientBrushVertexShader + : PositionWithLinearGradientBrushVertexShader; + break; + case Qt::ConicalGradientPattern: + srcPixelFragShaderName = ConicalGradientBrushSrcFragmentShader; + positionVertexShaderName = isAffine ? AffinePositionWithConicalGradientBrushVertexShader + : PositionWithConicalGradientBrushVertexShader; + break; + case Qt::RadialGradientPattern: + srcPixelFragShaderName = RadialGradientBrushSrcFragmentShader; + positionVertexShaderName = isAffine ? AffinePositionWithRadialGradientBrushVertexShader + : PositionWithRadialGradientBrushVertexShader; + break; + case Qt::TexturePattern: + srcPixelFragShaderName = TextureBrushSrcFragmentShader; + positionVertexShaderName = isAffine ? AffinePositionWithTextureBrushVertexShader + : PositionWithTextureBrushVertexShader; + break; + }; + compileNamedShader(positionVertexShaderName, QGLShader::PartialVertexShader); + compileNamedShader(srcPixelFragShaderName, QGLShader::PartialFragmentShader); + requiredProgram.positionVertexShader = compiledShaders[positionVertexShaderName]; + requiredProgram.srcPixelFragShader = compiledShaders[srcPixelFragShaderName]; + + + const bool hasCompose = compositionMode > QPainter::CompositionMode_Plus; + const bool hasMask = maskType != QGLEngineShaderManager::NoMask; + + // Choose fragment shader main function: + QGLEngineShaderManager::ShaderName mainFragShaderName; + + if (hasCompose && hasMask && useGlobalOpacity) + mainFragShaderName = MainFragmentShader_CMO; + if (hasCompose && hasMask && !useGlobalOpacity) + mainFragShaderName = MainFragmentShader_CM; + if (!hasCompose && hasMask && useGlobalOpacity) + mainFragShaderName = MainFragmentShader_MO; + if (!hasCompose && hasMask && !useGlobalOpacity) + mainFragShaderName = MainFragmentShader_M; + if (hasCompose && !hasMask && useGlobalOpacity) + mainFragShaderName = MainFragmentShader_CO; + if (hasCompose && !hasMask && !useGlobalOpacity) + mainFragShaderName = MainFragmentShader_C; + if (!hasCompose && !hasMask && useGlobalOpacity) + mainFragShaderName = MainFragmentShader_O; + if (!hasCompose && !hasMask && !useGlobalOpacity) + mainFragShaderName = MainFragmentShader; + + compileNamedShader(mainFragShaderName, QGLShader::PartialFragmentShader); + requiredProgram.mainFragShader = compiledShaders[mainFragShaderName]; + + if (hasMask) { + QGLEngineShaderManager::ShaderName maskShaderName = QGLEngineShaderManager::InvalidShaderName; + if (maskType == PixelMask) + maskShaderName = MaskFragmentShader; + else if (maskType == SubPixelMask) + maskShaderName = RgbMaskFragmentShader; + else if (maskType == SubPixelWithGammaMask) + maskShaderName = RgbMaskWithGammaFragmentShader; + else + qCritical("QGLEngineShaderManager::useCorrectShaderProg() - Unknown mask type"); + + compileNamedShader(maskShaderName, QGLShader::PartialFragmentShader); + requiredProgram.maskFragShader = compiledShaders[maskShaderName]; + } + else + requiredProgram.maskFragShader = 0; + + if (hasCompose) { + QGLEngineShaderManager::ShaderName compositionShaderName = QGLEngineShaderManager::InvalidShaderName; + switch (compositionMode) { + case QPainter::CompositionMode_Multiply: + compositionShaderName = MultiplyCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_Screen: + compositionShaderName = ScreenCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_Overlay: + compositionShaderName = OverlayCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_Darken: + compositionShaderName = DarkenCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_Lighten: + compositionShaderName = LightenCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_ColorDodge: + compositionShaderName = ColorDodgeCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_ColorBurn: + compositionShaderName = ColorBurnCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_HardLight: + compositionShaderName = HardLightCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_SoftLight: + compositionShaderName = SoftLightCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_Difference: + compositionShaderName = DifferenceCompositionModeFragmentShader; + break; + case QPainter::CompositionMode_Exclusion: + compositionShaderName = ExclusionCompositionModeFragmentShader; + break; + default: + qWarning("QGLEngineShaderManager::useCorrectShaderProg() - Unsupported composition mode"); + } + compileNamedShader(compositionShaderName, QGLShader::PartialFragmentShader); + requiredProgram.compositionFragShader = compiledShaders[compositionShaderName]; + } + else + requiredProgram.compositionFragShader = 0; + + + // At this point, requiredProgram is fully populated so try to find the program in the cache + foreach (const QGLEngineShaderProg &prog, cachedPrograms) { + if ( (prog.mainVertexShader == requiredProgram.mainVertexShader) + && (prog.positionVertexShader == requiredProgram.positionVertexShader) + && (prog.mainFragShader == requiredProgram.mainFragShader) + && (prog.srcPixelFragShader == requiredProgram.srcPixelFragShader) + && (prog.compositionFragShader == requiredProgram.compositionFragShader) ) + { + currentShaderProg = requiredProgram.program; + currentShaderProg->enable(); + shaderProgNeedsChanging = false; + return; + } + } + +/* + QGLShader* mainVertexShader; + QGLShader* positionVertexShader; + QGLShader* mainFragShader; + QGLShader* srcPixelFragShader; + QGLShader* maskFragShader; // Can be null for no mask + QGLShader* compositionFragShader; // Can be null for GL-handled mode + QGLShaderProgram* program; +*/ + // Shader program not found in cache, create it now. + requiredProgram.program = new QGLShaderProgram(ctx, this); + requiredProgram.program->addShader(requiredProgram.mainVertexShader); + requiredProgram.program->addShader(requiredProgram.positionVertexShader); + requiredProgram.program->addShader(requiredProgram.mainFragShader); + requiredProgram.program->addShader(requiredProgram.srcPixelFragShader); + requiredProgram.program->addShader(requiredProgram.maskFragShader); + requiredProgram.program->addShader(requiredProgram.compositionFragShader); + requiredProgram.program->link(); + if (!requiredProgram.program->isValid()) { + QString error; + qWarning() << "Shader program failed to link," +#if defined(QT_DEBUG) + << '\n' + << " Shaders Used:" << '\n' + << " mainVertexShader = " << requiredProgram.mainVertexShader->objectName() << '\n' + << " positionVertexShader = " << requiredProgram.positionVertexShader->objectName() << '\n' + << " mainFragShader = " << requiredProgram.mainFragShader->objectName() << '\n' + << " srcPixelFragShader = " << requiredProgram.srcPixelFragShader->objectName() << '\n' + << " maskFragShader = " << requiredProgram.maskFragShader->objectName() << '\n' + << " compositionFragShader = "<< requiredProgram.compositionFragShader->objectName() << '\n' +#endif + << " Error Log:" << '\n' + << " " << requiredProgram.program->errors(); + qWarning() << error; + } + else { + cachedPrograms.append(requiredProgram); + currentShaderProg = requiredProgram.program; + currentShaderProg->enable(); + } + shaderProgNeedsChanging = false; +} + +void QGLEngineShaderManager::compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type) +{ + if (compiledShaders[name]) + return; + + QGLShader *newShader = new QGLShader(type, ctx, this); + newShader->setSourceCode(qglEngineShaderSourceCode[name]); + // newShader->compile(); ### does not exist? + +#if defined(QT_DEBUG) + // Name the shader for easier debugging + QMetaEnum m = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("ShaderName")); + newShader->setObjectName(QLatin1String(m.valueToKey(name))); +#endif + + compiledShaders[name] = newShader; +} + + diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h new file mode 100644 index 0000000..fe30a70 --- /dev/null +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -0,0 +1,385 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +/* + VERTEX SHADERS + ============== + + Vertex shaders are specified as multiple (partial) shaders. On desktop, + this works fine. On ES, QGLShader & QGLShaderProgram will make partial + shaders work by concatenating the source in each QGLShader and compiling + it as a single shader. This is abstracted nicely by QGLShaderProgram and + the GL2 engine doesn't need to worry about it. + + Generally, there's two vertex shader objects. The position shaders are + the ones which set gl_Position. There's also two "main" vertex shaders, + one which just calls the position shader and another which also passes + through some texture coordinates from a vertex attribute array to a + varying. These texture coordinates are used for mask position in text + rendering and for the source coordinates in drawImage/drawPixmap. There's + also a "Simple" vertex shader for rendering a solid colour (used to render + into the stencil buffer where the actual colour value is discarded). + + The position shaders for brushes look scary. This is because many of the + calculations which logically belong in the fragment shader have been moved + into the vertex shader to improve performance. This is why the position + calculation is in a seperate shader. Not only does it calculate the + position, but it also calculates some data to be passed to the fragment + shader as a varying. It is optimal to move as much of the calculation as + possible into the vertex shader as this is executed less often. + + The varyings passed to the fragment shaders are interpolated (which is + cheap). Unfortunately, GL will apply perspective correction to the + interpolation calusing errors. To get around this, the vertex shader must + apply perspective correction itself and set the w-value of gl_Position to + zero. That way, GL will be tricked into thinking it doesn't need to apply a + perspective correction and use linear interpolation instead (which is what + we want). Of course, if the brush transform is affeine, no perspective + correction is needed and a simpler vertex shader can be used instead. + + So there are the following "main" vertex shaders: + qglslSimpleVertexShader + qglslMainVertexShader + qglslMainWithTexCoordsVertexShader + + And the the following position vertex shaders: + qglslPositionOnlyVertexShader + qglslPositionWithTextureBrushVertexShader + qglslPositionWithPatternBrushVertexShader + qglslPositionWithLinearGradientBrushVertexShader + qglslPositionWithRadialGradientBrushVertexShader + qglslPositionWithConicalGradientBrushVertexShader + qglslAffinePositionWithTextureBrushVertexShader + qglslAffinePositionWithPatternBrushVertexShader + qglslAffinePositionWithLinearGradientBrushVertexShader + qglslAffinePositionWithRadialGradientBrushVertexShader + qglslAffinePositionWithConicalGradientBrushVertexShader + + Leading to 23 possible vertex shaders + + + FRAGMENT SHADERS + ================ + + Fragment shaders are also specified as multiple (partial) shaders. The + different fragment shaders represent the different stages in Qt's fragment + pipeline. There are 1-3 stages in this pipeline: First stage is to get the + fragment's colour value. The next stage is to get the fragment's mask value + (coverage value for anti-aliasing) and the final stage is to blend the + incoming fragment with the background (for composition modes not supported + by GL). + + Of these, the first stage will always be present. If Qt doesn't need to + apply anti-aliasing (because it's off or handled by multisampling) then + the coverage value doesn't need to be applied. (Note: There are two types + of mask, one for regular anti-aliasing and one for sub-pixel anti- + aliasing.) If the composition mode is one which GL supports natively then + the blending stage doesn't need to be applied. + + As eash stage can have multiple implementations, they are abstracted as + GLSL function calls with the following signatures: + + Brushes & image drawing are implementations of "qcolorp vec4 srcPixel()": + qglslImageSrcFragShader + qglslNonPremultipliedImageSrcFragShader + qglslSolidBrushSrcFragShader + qglslTextureBrushSrcFragShader + qglslPatternBrushSrcFragShader + qglslLinearGradientBrushSrcFragShader + qglslRadialGradientBrushSrcFragShader + qglslConicalGradientBrushSrcFragShader + NOTE: It is assumed the colour returned by srcPixel() is pre-multiplied + + Masks are implementations of "qcolorp vec4 applyMask(qcolorp vec4 src)": + qglslMaskFragmentShader + qglslRgbMaskFragmentShader + qglslRgbMaskWithGammaFragmentShader + + Composition modes are "qcolorp vec4 compose(qcolorp vec4 src)": + qglslColorBurnCompositionModeFragmentShader + qglslColorDodgeCompositionModeFragmentShader + qglslDarkenCompositionModeFragmentShader + qglslDifferenceCompositionModeFragmentShader + qglslExclusionCompositionModeFragmentShader + qglslHardLightCompositionModeFragmentShader + qglslLightenCompositionModeFragmentShader + qglslMultiplyCompositionModeFragmentShader + qglslOverlayCompositionModeFragmentShader + qglslScreenCompositionModeFragmentShader + qglslSoftLightCompositionModeFragmentShader + + + Note: In the future, some GLSL compilers will support an extension allowing + a new 'color' precision specifier. To support this, qcolorp is used for + all color components so it can be defined to colorp or lowp depending upon + the implementation. + + So there are differnt frament shader main functions, depending on the + number & type of pipelines the fragment needs to go through. + + The choice of which main() fragment shader string to use depends on: + - Use of global opacity + - Brush style (some brushes apply opacity themselves) + - Use & type of mask (TODO: Need to support high quality anti-aliasing & text) + - Use of non-GL Composition mode + + Leading to the following fragment shader main functions: + gl_FragColor = compose(applyMask(srcPixel()*globalOpacity)); + gl_FragColor = compose(applyMask(srcPixel())); + gl_FragColor = applyMask(srcPixel()*globalOpacity); + gl_FragColor = applyMask(srcPixel()); + gl_FragColor = compose(srcPixel()*globalOpacity); + gl_FragColor = compose(srcPixel()); + gl_FragColor = srcPixel()*globalOpacity; + gl_FragColor = srcPixel(); + + Called: + qglslMainFragmentShader_CMO + qglslMainFragmentShader_CM + qglslMainFragmentShader_MO + qglslMainFragmentShader_M + qglslMainFragmentShader_CO + qglslMainFragmentShader_C + qglslMainFragmentShader_O + qglslMainFragmentShader + + Where: + M = Mask + C = Composition + O = Global Opacity + + + CUSTOM SHADER CODE (idea, depricated) + ================== + + The use of custom shader code is supported by the engine for drawImage and + drawPixmap calls. This is implemented via hooks in the fragment pipeline. + The custom shader is passed to the engine as a partial fragment shader + (QGLCustomizedShader). The shader will implement a pre-defined method name + which Qt's fragment pipeline will call. There are two different hooks which + can be implemented as custom shader code: + + mediump vec4 customShader(sampler2d src, vec2 srcCoords) + mediump vec4 customShaderWithDest(sampler2d dest, sampler2d src, vec2 srcCoords) + +*/ + +#ifndef QGLENGINE_SHADER_MANAGER_H +#define QGLENGINE_SHADER_MANAGER_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(OpenGL) + + +struct QGLEngineShaderProg +{ + QGLShader* mainVertexShader; + QGLShader* positionVertexShader; + QGLShader* mainFragShader; + QGLShader* srcPixelFragShader; + QGLShader* maskFragShader; // Can be null for no mask + QGLShader* compositionFragShader; // Can be null for GL-handled mode + QGLShaderProgram* program; +}; + +/* +struct QGLEngineCachedShaderProg +{ + QGLEngineCachedShaderProg(QGLEngineShaderManager::ShaderName vertexMain, + QGLEngineShaderManager::ShaderName vertexPosition, + QGLEngineShaderManager::ShaderName fragMain, + QGLEngineShaderManager::ShaderName pixelSrc, + QGLEngineShaderManager::ShaderName mask, + QGLEngineShaderManager::ShaderName composition); + + int cacheKey; + QGLShaderProgram* program; +} +*/ + +class QGLEngineShaderManager : public QObject +{ + Q_OBJECT; +public: + QGLEngineShaderManager(QGLContext* context); + ~QGLEngineShaderManager(); + + enum MaskType {NoMask, PixelMask, SubPixelMask, SubPixelWithGammaMask}; + enum PixelSrcType { + ImageSrc = Qt::TexturePattern+1, + NonPremultipliedImageSrc = Qt::TexturePattern+2 + }; + + // There are optimisations we can do, depending on the transform: + // 1) May not have to apply perspective-correction + // 2) Can use lower precision for vertecies + void optimiseForBrushTransform(const QTransform transform); + void setSrcPixelType(Qt::BrushStyle); + void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images + void setTextureCoordsEnabled(bool); // For images & text glyphs + void setUseGlobalOpacity(bool); + void setMaskType(MaskType); + void setCompositionMode(QPainter::CompositionMode); + + bool shaderProgramDirty(); // returns true if the shader program needs to be changed + void useCorrectShaderProg(); + + QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen + QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers + + enum ShaderName { + SimpleVertexShader, + MainVertexShader, + MainWithTexCoordsVertexShader, + + PositionOnlyVertexShader, + PositionWithPatternBrushVertexShader, + PositionWithLinearGradientBrushVertexShader, + PositionWithConicalGradientBrushVertexShader, + PositionWithRadialGradientBrushVertexShader, + PositionWithTextureBrushVertexShader, + AffinePositionWithPatternBrushVertexShader, + AffinePositionWithLinearGradientBrushVertexShader, + AffinePositionWithConicalGradientBrushVertexShader, + AffinePositionWithRadialGradientBrushVertexShader, + AffinePositionWithTextureBrushVertexShader, + + MainFragmentShader_CMO, + MainFragmentShader_CM, + MainFragmentShader_MO, + MainFragmentShader_M, + MainFragmentShader_CO, + MainFragmentShader_C, + MainFragmentShader_O, + MainFragmentShader, + + ImageSrcFragmentShader, + NonPremultipliedImageSrcFragmentShader, + SolidBrushSrcFragmentShader, + TextureBrushSrcFragmentShader, + PatternBrushSrcFragmentShader, + LinearGradientBrushSrcFragmentShader, + RadialGradientBrushSrcFragmentShader, + ConicalGradientBrushSrcFragmentShader, + + MaskFragmentShader, + RgbMaskFragmentShader, + RgbMaskWithGammaFragmentShader, + + MultiplyCompositionModeFragmentShader, + ScreenCompositionModeFragmentShader, + OverlayCompositionModeFragmentShader, + DarkenCompositionModeFragmentShader, + LightenCompositionModeFragmentShader, + ColorDodgeCompositionModeFragmentShader, + ColorBurnCompositionModeFragmentShader, + HardLightCompositionModeFragmentShader, + SoftLightCompositionModeFragmentShader, + DifferenceCompositionModeFragmentShader, + ExclusionCompositionModeFragmentShader, + + TotalShaderCount, InvalidShaderName + }; + +/* + // These allow the ShaderName enum to be used as a cache key + const int mainVertexOffset = 0; + const int positionVertexOffset = (1<<2) - PositionOnlyVertexShader; + const int mainFragOffset = (1<<6) - MainFragmentShader_CMO; + const int srcPixelOffset = (1<<10) - ImageSrcFragmentShader; + const int maskOffset = (1<<14) - NoMaskShader; + const int compositionOffset = (1 << 16) - MultiplyCompositionModeFragmentShader; +*/ + +#if defined (QT_DEBUG) + Q_ENUMS(ShaderName); +#else +#error Release build not supported yet +#endif + + +private: + QGLContext* ctx; + bool shaderProgNeedsChanging; + + // Current state variables which influence the choice of shader: + QTransform transform; + int srcPixelType; + bool useGlobalOpacity; + MaskType maskType; + bool useTextureCoords; + QPainter::CompositionMode compositionMode; + + QGLShaderProgram* simpleShaderProg; + QGLShaderProgram* currentShaderProg; + + // TODO: Possibly convert to a LUT + QList cachedPrograms; + + QGLShader* compiledShaders[TotalShaderCount]; + + void compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type); +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //QGLENGINE_SHADER_MANAGER_H diff --git a/src/opengl/gl2paintengineex/qglpexshadermanager.cpp b/src/opengl/gl2paintengineex/qglpexshadermanager.cpp deleted file mode 100644 index e460e08..0000000 --- a/src/opengl/gl2paintengineex/qglpexshadermanager.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglpexshadermanager_p.h" - -#include "glgc_shader_source.h" - -QGLPEXShaderManager::QGLPEXShaderManager(const QGLContext* context) -{ - ctx = const_cast(context); - - defaultVertexShader= new QGLShader(QGLShader::VertexShader, context); - defaultVertexShader->addSource(QLatin1String(qglslDefaultVertexShader)); - if (!defaultVertexShader->compile()) - qWarning() << "Default vertex shader failed to compile: " << defaultVertexShader->log(); - - noBrushShader = new QGLShader(QGLShader::FragmentShader, context); - noBrushShader->addSource(QLatin1String(qglslFragmentShaderMain)); - noBrushShader->addSource(QLatin1String(qglslNoBrushFragmentShader)); - if (!noBrushShader->compile()) - qWarning() << "No brush shader failed to compile:" << noBrushShader->log(); - - - // Create a program for noBrush: - QGLShaderProgram* noBrushProg = new QGLShaderProgram(ctx); - noBrushProg->addShader(defaultVertexShader); - noBrushProg->addShader(noBrushShader); - if (!noBrushProg->link()) - qWarning() << "NoBrush shader program failed to link:" << noBrushProg->log(); - - // Add noBrush Program to cache: - QGLCachedShaderProg cachedProg; - cachedProg.vertexShader = defaultVertexShader; - cachedProg.brushShader = noBrushShader; - cachedProg.compositionShader = 0; - cachedProg.shader = noBrushProg; - cachedPrograms.append(cachedProg); - - - // Set state - useGlobalOpacity = true; - currentBrushStyle = Qt::NoBrush; - currentTransformType = FullTransform; - shaderProgNeedsChanging = false; - activeProgram = noBrushProg; - - solidBrushShader = 0; - - conicalBrushVertexShader = 0; - conicalBrushFragmentShader = 0; - - radialBrushVertexShader = 0; - radialBrushFragmentShader = 0; - - linearBrushVertexShader = 0; - linearBrushFragmentShader = 0; - - patternBrushVertexShader = 0; - patternBrushFragmentShader = 0; - - textureBrushFragmentShader = 0; - textureBrushVertexShader = 0; - - simpleFragmentShader = 0; - simpleShaderProgram = 0; - - imageVertexShader = 0; - imageFragmentShader = 0; - imageShaderProgram = 0; - - textVertexShader = 0; - textFragmentShader = 0; - textShaderProgram = 0; -} - -QGLPEXShaderManager::~QGLPEXShaderManager() -{ - delete defaultVertexShader; - delete imageVertexShader; - delete imageFragmentShader; - delete imageShaderProgram; - delete textVertexShader; - delete textFragmentShader; - delete textShaderProgram; - delete noBrushShader; - delete solidBrushShader; - - delete conicalBrushVertexShader; - delete conicalBrushFragmentShader; - - delete radialBrushVertexShader; - delete radialBrushFragmentShader; - - delete linearBrushFragmentShader; - delete linearBrushVertexShader; - - delete patternBrushFragmentShader; - delete patternBrushVertexShader; - - delete textureBrushFragmentShader; - delete textureBrushVertexShader; - - delete simpleFragmentShader; - delete simpleShaderProgram; -} - -void QGLPEXShaderManager::setUseGlobalOpacity(bool value) -{ - if (value != useGlobalOpacity) - shaderProgNeedsChanging = true; - - useGlobalOpacity = value; -} - -void QGLPEXShaderManager::setBrushStyle(Qt::BrushStyle style) -{ - if (currentBrushStyle != style) - shaderProgNeedsChanging = true; - - currentBrushStyle = style; -} - -void QGLPEXShaderManager::setAffineOnlyBrushTransform(bool value) -{ - Q_UNUSED(value); - // TODO -} - -bool QGLPEXShaderManager::useCorrectShaderProg() -{ - if (!shaderProgNeedsChanging) { - activeProgram->use(); - return false; - } - - const char* fragmentShaderMainSrc = qglslFragmentShaderMain; - QGLShader* vertexShader = defaultVertexShader; - QGLShader* fragmentShader = noBrushShader; - - // Make sure we compile up the correct brush shader - switch (currentBrushStyle) { - case Qt::NoBrush: - break; - case Qt::SolidPattern: - if (!solidBrushShader) { - qDebug("Compiling qglslSolidBrushFragmentShader"); - solidBrushShader = new QGLShader(QGLShader::FragmentShader, ctx); - solidBrushShader->addSource(QLatin1String(qglslNoOpacityFragmentShaderMain)); - solidBrushShader->addSource(QLatin1String(qglslSolidBrushFragmentShader)); - if (!solidBrushShader->compile()) - qWarning() << "qglslSolidBrush failed to compile:" << solidBrushShader->log(); - } - fragmentShader = solidBrushShader; - break; - case Qt::TexturePattern: - if (!textureBrushVertexShader) { - qDebug("Compiling qglslTextureBrushVertexShader"); - textureBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx); - textureBrushVertexShader->addSource(QLatin1String(qglslTextureBrushVertexShader)); - if (!textureBrushVertexShader->compile()) { - qWarning() << "qglslTextureBrushVertexShader failed to compile: " - << textureBrushVertexShader->log(); - } - } - vertexShader = textureBrushVertexShader; - - if (!textureBrushFragmentShader) { - qDebug("Compiling qglslTextureBrushFragmentShader"); - textureBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx); - textureBrushFragmentShader->addSource(QLatin1String(fragmentShaderMainSrc)); - textureBrushFragmentShader->addSource(QLatin1String(qglslTextureBrushFragmentShader)); - if (!textureBrushFragmentShader->compile()) { - qWarning() << "qglslTextureBrushFragmentShader failed to compile:" - << textureBrushFragmentShader->log(); - } - } - fragmentShader = textureBrushFragmentShader; - break; - case Qt::LinearGradientPattern: - if (!linearBrushVertexShader) { - qDebug("Compiling qglslLinearGradientBrushVertexShader"); - linearBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx); - linearBrushVertexShader->addSource(QLatin1String(qglslLinearGradientBrushVertexShader)); - if (!linearBrushVertexShader->compile()) { - qWarning() << "qglslLinearGradientBrushVertexShader failed to compile: " - << linearBrushVertexShader->log(); - } - } - vertexShader = linearBrushVertexShader; - - if (!linearBrushFragmentShader) { - qDebug("Compiling qglslLinearGradientBrushFragmentShader"); - linearBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx); - linearBrushFragmentShader->addSource(QLatin1String(fragmentShaderMainSrc)); - linearBrushFragmentShader->addSource(QLatin1String(qglslLinearGradientBrushFragmentShader)); - if (!linearBrushFragmentShader->compile()) { - qWarning() << "qglslLinearGradientBrushFragmentShader failed to compile:" - << linearBrushFragmentShader->log(); - } - } - fragmentShader = linearBrushFragmentShader; - break; - case Qt::RadialGradientPattern: - if (!radialBrushVertexShader) { - qDebug("Compiling qglslRadialGradientBrushVertexShader"); - radialBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx); - radialBrushVertexShader->addSource(QLatin1String(qglslRadialGradientBrushVertexShader)); - if (!radialBrushVertexShader->compile()) { - qWarning() << "qglslRadialGradientBrushVertexShader failed to compile: " - << radialBrushVertexShader->log(); - } - } - vertexShader = radialBrushVertexShader; - - if (!radialBrushFragmentShader) { - qDebug("Compiling qglslRadialGradientBrushFragmentShader"); - radialBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx); - radialBrushFragmentShader->addSource(QLatin1String(fragmentShaderMainSrc)); - radialBrushFragmentShader->addSource(QLatin1String(qglslRadialGradientBrushFragmentShader)); - if (!radialBrushFragmentShader->compile()) { - qWarning() << "qglslRadialGradientBrushFragmentShader failed to compile:" - << radialBrushFragmentShader->log(); - } - } - fragmentShader = radialBrushFragmentShader; - break; - case Qt::ConicalGradientPattern: - // FIXME: We currently use the same vertex shader as radial brush - if (!conicalBrushVertexShader) { - qDebug("Compiling qglslConicalGradientBrushVertexShader"); - conicalBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx); - conicalBrushVertexShader->addSource(QLatin1String(qglslConicalGradientBrushVertexShader)); - if (!conicalBrushVertexShader->compile()) { - qWarning() << "qglslConicalGradientBrushVertexShader failed to compile: " - << conicalBrushVertexShader->log(); - } - } - vertexShader = conicalBrushVertexShader; - - if (!conicalBrushFragmentShader) { - qDebug("Compiling qglslConicalGradientBrushFragmentShader"); - conicalBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx); - conicalBrushFragmentShader->addSource(QLatin1String(fragmentShaderMainSrc)); - conicalBrushFragmentShader->addSource(QLatin1String(qglslConicalGradientBrushFragmentShader)); - if (!conicalBrushFragmentShader->compile()) { - qWarning() << "qglslConicalGradientBrushFragmentShader failed to compile:" - << conicalBrushFragmentShader->log(); - } - } - fragmentShader = conicalBrushFragmentShader; - break; - case Qt::Dense1Pattern: - case Qt::Dense2Pattern: - case Qt::Dense3Pattern: - case Qt::Dense4Pattern: - case Qt::Dense5Pattern: - case Qt::Dense6Pattern: - case Qt::Dense7Pattern: - case Qt::HorPattern: - case Qt::VerPattern: - case Qt::CrossPattern: - case Qt::BDiagPattern: - case Qt::FDiagPattern: - case Qt::DiagCrossPattern: - if (!patternBrushVertexShader) { - qDebug("Compiling qglslPatternBrushVertexShader"); - patternBrushVertexShader = new QGLShader(QGLShader::VertexShader, ctx); - patternBrushVertexShader->addSource(QLatin1String(qglslPatternBrushVertexShader)); - if (!patternBrushVertexShader->compile()) { - qWarning() << "qglslPatternBrushVertexShader failed to compile: " - << patternBrushVertexShader->log(); - } - } - vertexShader = patternBrushVertexShader; - - if (!patternBrushFragmentShader) { - qDebug("Compiling qglslPatternBrushFragmentShader"); - patternBrushFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx); - patternBrushFragmentShader->addSource(QLatin1String(qglslNoOpacityFragmentShaderMain)); - patternBrushFragmentShader->addSource(QLatin1String(qglslPatternBrushFragmentShader)); - if (!patternBrushFragmentShader->compile()) { - qWarning() << "qglslPatternBrushFragmentShader failed to compile:" - << patternBrushFragmentShader->log(); - } - } - fragmentShader = patternBrushFragmentShader; - break; - default: - qWarning("Unimplemented brush style (%d)", currentBrushStyle); - } - - // Now newBrushShader is set correctly, check to see if we already have the program - // already linked and ready to go in the cache: - bool foundProgram = false; - foreach (QGLCachedShaderProg cachedProg, cachedPrograms) { - if ((cachedProg.vertexShader == vertexShader) && - (cachedProg.brushShader == fragmentShader) && - (cachedProg.compositionShader == 0) ) { - - activeProgram = cachedProg.shader; - foundProgram = true; - break; - } - } - - if (!foundProgram) { - qDebug() << "Linking shader program for " << currentBrushStyle; - // Required program not found - create it. - QGLShaderProgram* newProg = new QGLShaderProgram(ctx); - - newProg->addShader(vertexShader); - newProg->addShader(fragmentShader); - - if (!newProg->link()) - qWarning() << "Shader program for " << currentBrushStyle << "failed to link:" << newProg->log(); - - QGLCachedShaderProg cachedProg; - cachedProg.vertexShader = vertexShader; - cachedProg.brushShader = fragmentShader; - cachedProg.compositionShader = 0; - cachedProg.shader = newProg; - - cachedPrograms.append(cachedProg); - activeProgram = newProg; - } - - activeProgram->use(); - shaderProgNeedsChanging = false; - return true; -} - -QGLShaderProgram* QGLPEXShaderManager::brushShader() -{ - return activeProgram; -} - -// The only uniform the simple shader has is the PMV matrix -QGLShaderProgram* QGLPEXShaderManager::simpleShader() -{ - if (!simpleShaderProgram) { - simpleShaderProgram = new QGLShaderProgram(ctx); - - if (!simpleFragmentShader) { - simpleFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx); - simpleFragmentShader->addSource(QLatin1String(qglslSimpleFragmentShader)); - if (!simpleFragmentShader->compile()) - qWarning() << "qglslSimpleFragmentShader failed to compile:" << simpleFragmentShader->log(); - } - - simpleShaderProgram->addShader(defaultVertexShader); - simpleShaderProgram->addShader(simpleFragmentShader); - if (!simpleShaderProgram->link()) - qWarning() << "Simple shader program failed to link:" << simpleShaderProgram->log(); - } - - return simpleShaderProgram; -} - -QGLShaderProgram* QGLPEXShaderManager::imageShader() -{ - if (!imageShaderProgram) { - if (!imageVertexShader) { - imageVertexShader = new QGLShader(QGLShader::VertexShader, ctx); - imageVertexShader->addSource(QLatin1String(qglslImageVertexShader)); - if (!imageVertexShader->compile()) - qWarning() << "Image/Pixmap vertex shader failed to compile:" << imageVertexShader->log(); - } - - if (!imageFragmentShader) { - imageFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx); - imageFragmentShader->addSource(QLatin1String(qglslImageFragmentShader)); - if (!imageFragmentShader->compile()) - qWarning() << "Image/Pixmap fragment shader failed to compile:" << imageFragmentShader->log(); - } - - imageShaderProgram = new QGLShaderProgram(ctx); - imageShaderProgram->addShader(imageVertexShader); - imageShaderProgram->addShader(imageFragmentShader); - if (!imageShaderProgram->link()) - qWarning() << "Image/Pixmap shader program failed to link:" << imageShaderProgram->log(); - } - - return imageShaderProgram; -} - -QGLShaderProgram* QGLPEXShaderManager::textShader() -{ - if (!textShaderProgram) { - if (!textVertexShader) { - textVertexShader = new QGLShader(QGLShader::VertexShader, ctx); - textVertexShader->addSource(QLatin1String(qglslImageVertexShader)); - if (!textVertexShader->compile()) - qWarning() << "Text vertex shader failed to compile:" << textVertexShader->log(); - } - - if (!textFragmentShader) { - textFragmentShader = new QGLShader(QGLShader::FragmentShader, ctx); - textFragmentShader->addSource(QLatin1String(qglslTextFragmentShader)); - if (!textFragmentShader->compile()) - qWarning() << "Text fragment shader failed to compile:" << textFragmentShader->log(); - } - - textShaderProgram = new QGLShaderProgram(ctx); - textShaderProgram->addShader(textVertexShader); - textShaderProgram->addShader(textFragmentShader); - if (!textShaderProgram->link()) - qWarning() << "Text shader program failed to link:" << textShaderProgram->log(); - } - - return textShaderProgram; -} - diff --git a/src/opengl/gl2paintengineex/qglpexshadermanager_p.h b/src/opengl/gl2paintengineex/qglpexshadermanager_p.h deleted file mode 100644 index c8f47b2..0000000 --- a/src/opengl/gl2paintengineex/qglpexshadermanager_p.h +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qglshader_p.h" - - -// Worstcase combo: Brush->Mask->Composition - -/* - Vertex shader source is specified with a single string. This string - contains the main function and sets the gl_Position. The choice of - which vertex shader to use depends on: - - Brush style - - Brush transform->isAffine() - - Fragment shaders are specified as multiple strings, one for the main - function, one for the brush calculation and optionally one for the - extended composition mode. Brushes are implementations of - "mediump vec4 brush()" - Composition modes are implemented as a - "mediump vec4 compose(mediump vec4 color)" - NOTE: Precision may change in future. - - The choice of which main() fragment shader string to use depends on: - - Global opacity - - Brush style (some brushes apply opacity themselves) - - Use of mask (TODO: Need to support high quality anti-aliasing & text) - - Composition mode - - The choice of which brush() fragment shader to use depends on: - - Brush style - -*/ - - -struct QGLCachedShaderProg -{ - QGLShader* vertexShader; - QGLShader* brushShader; - QGLShader* compositionShader; - QGLShaderProgram* shader; -}; - -class QGLPEXShaderManager -{ -public: - QGLPEXShaderManager(const QGLContext* context); - ~QGLPEXShaderManager(); - - enum TransformType {IdentityTransform, ScaleTransform, TranslateTransform, FullTransform}; - - void optimiseForBrushTransform(const QTransform& transform); - void setBrushStyle(Qt::BrushStyle style); - void setUseGlobalOpacity(bool value); - void setAffineOnlyBrushTransform(bool value); // I.e. Do we need to apply perspective-correction? - // Not doing so saves some vertex shader calculations. - - bool useCorrectShaderProg(); // returns true if the shader program has changed - - QGLShaderProgram* brushShader(); - QGLShaderProgram* simpleShader(); // Used to draw into e.g. stencil buffers - QGLShaderProgram* imageShader(); - QGLShaderProgram* textShader(); - -private: - QGLShader* defaultVertexShader; - - QGLShader* imageVertexShader; - QGLShader* imageFragmentShader; - QGLShaderProgram* imageShaderProgram; - - QGLShader* textVertexShader; - QGLShader* textFragmentShader; - QGLShaderProgram* textShaderProgram; - - QGLShader* noBrushShader; - QGLShader* solidBrushShader; - - QGLShader* conicalBrushVertexShader; - QGLShader* conicalBrushFragmentShader; - - QGLShader* radialBrushVertexShader; - QGLShader* radialBrushFragmentShader; - - QGLShader* linearBrushVertexShader; - QGLShader* linearBrushFragmentShader; - - QGLShader* patternBrushVertexShader; - QGLShader* patternBrushFragmentShader; - - QGLShader* textureBrushFragmentShader; - QGLShader* textureBrushVertexShader; - - QGLShader* simpleFragmentShader; - QGLShaderProgram* simpleShaderProgram; - - QGLShaderProgram* activeProgram; - - Qt::BrushStyle currentBrushStyle; - bool useGlobalOpacity; - TransformType currentTransformType; - bool shaderProgNeedsChanging; - - QList cachedPrograms; - - QGLContext* ctx; -}; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 89ed1f7..53ae4fb 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -77,7 +77,7 @@ #include #include "qglgradientcache_p.h" -#include "qglpexshadermanager_p.h" +#include "qglengineshadermanager_p.h" #include "qgl2pexvertexarray_p.h" @@ -170,7 +170,7 @@ public: GLfloat pmvMatrix[4][4]; - QGLPEXShaderManager* shaderManager; + QGLEngineShaderManager* shaderManager; // Clipping & state stuff stolen from QOpenGLPaintEngine: void updateDepthClip(); diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 3b8bfa1..1527f2d 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -43,16 +43,15 @@ SOURCES += qgl.cpp \ #contains(QT_CONFIG, opengles2) { SOURCES += gl2paintengineex/qglgradientcache.cpp \ - gl2paintengineex/qglpexshadermanager.cpp \ - gl2paintengineex/qglshader.cpp \ + gl2paintengineex/qglengineshadermanager.cpp \ gl2paintengineex/qgl2pexvertexarray.cpp \ gl2paintengineex/qpaintengineex_opengl2.cpp HEADERS += gl2paintengineex/qglgradientcache_p.h \ - gl2paintengineex/qglpexshadermanager_p.h \ - gl2paintengineex/qglshader_p.h \ + gl2paintengineex/qglengineshadermanager_p.h \ gl2paintengineex/qgl2pexvertexarray_p.h \ - gl2paintengineex/qpaintengineex_opengl2_p.h + gl2paintengineex/qpaintengineex_opengl2_p.h \ + gl2paintengineex/glgc_shader_source.h #} -- cgit v0.12 From 3cdaa8ed05a6af3dabcbc82388fc75c0e2ae8f71 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 15 Apr 2009 14:33:39 +0200 Subject: Adapt GL2 Paint Engine to new math3d, shader & shader manager APIs --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 86 +++++++++++----------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 53ae4fb..f1918c8 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -219,21 +219,21 @@ void QGL2PaintEngineExPrivate::setBrush(const QBrush* brush) currentBrush = brush; brushTextureDirty = true; brushUniformsDirty = true; - shaderManager->setBrushStyle(currentBrush->style()); - shaderManager->setAffineOnlyBrushTransform(currentBrush->transform().isAffine()); + shaderManager->setSrcPixelType(currentBrush->style()); + shaderManager->optimiseForBrushTransform(currentBrush->transform()); } // Unless this gets used elsewhere, it's probably best to merge it into fillStencilWithVertexArray void QGL2PaintEngineExPrivate::useSimpleShader() { - shaderManager->simpleShader()->use(); + shaderManager->simpleProgram()->enable(); if (matrixDirty) updateMatrix(); if (simpleShaderMatrixUniformDirty) { - shaderManager->simpleShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; + shaderManager->simpleProgram()->setUniformValue("pmvMatrix", pmvMatrix); simpleShaderMatrixUniformDirty = false; } } @@ -300,7 +300,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() if (style == Qt::SolidPattern) { QColor col = premultiplyColor(currentBrush->color(), opacity); - shaderManager->brushShader()->uniforms()[QLatin1String("fragmentColor")] = col; + shaderManager->currentProgram()->setUniformValue("fragmentColor", col); setOpacity = false; } else { @@ -312,11 +312,11 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QColor col = premultiplyColor(currentBrush->color(), opacity); - shaderManager->brushShader()->uniforms()[QLatin1String("patternColor")] = col; + shaderManager->currentProgram()->setUniformValue("patternColor", col); setOpacity = false; //So code below doesn't try to set the opacity uniform - QGLVec2 halfViewportSize = { width*0.5, height*0.5 }; - shaderManager->brushShader()->uniforms()[QLatin1String("halfViewportSize")] = halfViewportSize; + QVector2D halfViewportSize(width*0.5, height*0.5); + shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize); } else if (style == Qt::LinearGradientPattern) { const QLinearGradient *g = static_cast(currentBrush->gradient()); @@ -327,17 +327,16 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QPointF l = realFinal - realStart; - // ### - QGLVec3 linearData = { + QVector3D linearData( l.x(), l.y(), 1.0f / (l.x() * l.x() + l.y() * l.y()) - }; + ); - shaderManager->brushShader()->uniforms()[QLatin1String("linearData")] = linearData; + shaderManager->currentProgram()->setUniformValue("linearData", linearData); - QGLVec2 halfViewportSize = { width*0.5, height*0.5 }; - shaderManager->brushShader()->uniforms()[QLatin1String("halfViewportSize")] = halfViewportSize; + QVector2D halfViewportSize(width*0.5, height*0.5); + shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize); } else if (style == Qt::ConicalGradientPattern) { const QConicalGradient *g = static_cast(currentBrush->gradient()); @@ -345,10 +344,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() GLfloat angle = -(g->angle() * 2 * Q_PI) / 360.0; - shaderManager->brushShader()->uniforms()[QLatin1String("angle")] = angle; + shaderManager->currentProgram()->setUniformValue("angle", angle); - QGLVec2 halfViewportSize = { width*0.5, height*0.5 }; - shaderManager->brushShader()->uniforms()[QLatin1String("halfViewportSize")] = halfViewportSize; + QVector2D halfViewportSize(width*0.5, height*0.5); + shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize); } else if (style == Qt::RadialGradientPattern) { const QRadialGradient *g = static_cast(currentBrush->gradient()); @@ -358,16 +357,15 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() translationPoint = realFocal; QPointF fmp = realCenter - realFocal; - shaderManager->brushShader()->uniforms()[QLatin1String("fmp")] = fmp; + shaderManager->currentProgram()->setUniformValue("fmp", fmp); GLfloat fmp2_m_radius2 = -fmp.x() * fmp.x() - fmp.y() * fmp.y() + realRadius*realRadius; - shaderManager->brushShader()->uniforms()[QLatin1String("fmp2_m_radius2")] = fmp2_m_radius2; + shaderManager->currentProgram()->setUniformValue("fmp2_m_radius2", fmp2_m_radius2); + shaderManager->currentProgram()->setUniformValue("inverse_2_fmp2_m_radius2", + GLfloat(1.0 / (2.0*fmp2_m_radius2))); - shaderManager->brushShader()->uniforms()[QLatin1String("inverse_2_fmp2_m_radius2")] = - GLfloat(1.0 / (2.0*fmp2_m_radius2)); - - QGLVec2 halfViewportSize = { width*0.5, height*0.5 }; - shaderManager->brushShader()->uniforms()[QLatin1String("halfViewportSize")] = halfViewportSize; + QVector2D halfViewportSize(width*0.5, height*0.5); + shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize); } else if (style == Qt::TexturePattern) { translationPoint = q->state()->brushOrigin; @@ -375,10 +373,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() const QPixmap& texPixmap = currentBrush->texture(); QSizeF invertedTextureSize( 1.0 / texPixmap.width(), 1.0 / texPixmap.height() ); - shaderManager->brushShader()->uniforms()[QLatin1String("invertedTextureSize")] = invertedTextureSize; + shaderManager->currentProgram()->setUniformValue("invertedTextureSize", invertedTextureSize); - QGLVec2 halfViewportSize = { width*0.5, height*0.5 }; - shaderManager->brushShader()->uniforms()[QLatin1String("halfViewportSize")] = halfViewportSize; + QVector2D halfViewportSize(width*0.5, height*0.5); + shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize); } else qWarning("QGL2PaintEngineEx: Unimplemented fill style"); @@ -387,11 +385,11 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() QTransform gl_to_qt(1, 0, 0, -1, 0, height); QTransform inv_matrix = gl_to_qt * (brushQTransform * q->state()->matrix).inverted() * translate; - shaderManager->brushShader()->uniforms()[QLatin1String("brushTransform")] = inv_matrix; - shaderManager->brushShader()->uniforms()[QLatin1String("brushTexture")] = QT_BRUSH_TEXTURE_UNIT; + shaderManager->currentProgram()->setUniformValue("brushTransform", inv_matrix); + shaderManager->currentProgram()->setUniformValue("brushTexture", QT_BRUSH_TEXTURE_UNIT); if (setOpacity) - shaderManager->brushShader()->uniforms()[QLatin1String("opacity")] = opacity; + shaderManager->currentProgram()->setUniformValue("opacity", opacity); } brushUniformsDirty = false; } @@ -524,12 +522,12 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s updateMatrix(); if (imageShaderMatrixUniformDirty) { - shaderManager->imageShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; +// shaderManager->imageShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; imageShaderMatrixUniformDirty = false; } - if (q->state()->opacity < 0.99f) - shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)q->state()->opacity; +// if (q->state()->opacity < 0.99f) +// shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)q->state()->opacity; GLfloat dx = 1.0 / textureSize.width(); GLfloat dy = 1.0 / textureSize.height(); @@ -562,15 +560,15 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); - shaderManager->textShader()->use(); - shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; +// shaderManager->textShader()->use(); +// shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; } if (newMode == ImageDrawingMode) { // We have a shader specifically for drawPixmap/drawImage... - shaderManager->imageShader()->use(); - shaderManager->imageShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; - shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)1.0; +// shaderManager->imageShader()->use(); +// shaderManager->imageShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; +// shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)1.0; glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); @@ -727,7 +725,9 @@ void QGL2PaintEngineExPrivate::prepareForDraw() if (compositionModeDirty) updateCompositionMode(); - if (shaderManager->useCorrectShaderProg()) { + if (shaderManager->shaderProgramDirty()) { + shaderManager->useCorrectShaderProg(); + // The shader program has changed so mark all uniforms as dirty: brushUniformsDirty = true; brushShaderMatrixUniformDirty = true; @@ -737,7 +737,7 @@ void QGL2PaintEngineExPrivate::prepareForDraw() updateBrushUniforms(); if (brushShaderMatrixUniformDirty) { - shaderManager->brushShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; + shaderManager->currentProgram()->setUniformValue("pmvMatrix", pmvMatrix); brushShaderMatrixUniformDirty = false; } @@ -984,12 +984,12 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte updateMatrix(); if (textShaderMatrixUniformDirty) { - shaderManager->textShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; +// shaderManager->textShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; textShaderMatrixUniformDirty = false; } QColor col = premultiplyColor(s->pen.color(), (GLfloat)s->opacity); - shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col; +// shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col; GLfloat dx = 1.0 / image.width(); GLfloat dy = 1.0 / image.height(); @@ -1035,7 +1035,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) qt_resolve_glsl_extensions(d->ctx); if (!d->shaderManager) - d->shaderManager = new QGLPEXShaderManager(d->ctx); + d->shaderManager = new QGLEngineShaderManager(d->ctx); glViewport(0, 0, d->width, d->height); -- cgit v0.12 From 5c92012d6ee57f644f62af5732a27899f2a1f462 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 16 Apr 2009 15:31:16 +0200 Subject: Clean up existing & implement missing GLSL for new shader manager --- src/opengl/gl2paintengineex/glgc_shader_source.h | 290 ---------------- .../gl2paintengineex/qglengineshadermanager.cpp | 88 ++++- .../gl2paintengineex/qglengineshadermanager_p.h | 3 +- .../gl2paintengineex/qglengineshadersource_p.h | 385 +++++++++++++++++++++ src/opengl/opengl.pro | 2 +- 5 files changed, 467 insertions(+), 301 deletions(-) delete mode 100644 src/opengl/gl2paintengineex/glgc_shader_source.h create mode 100644 src/opengl/gl2paintengineex/qglengineshadersource_p.h diff --git a/src/opengl/gl2paintengineex/glgc_shader_source.h b/src/opengl/gl2paintengineex/glgc_shader_source.h deleted file mode 100644 index 5184c78..0000000 --- a/src/opengl/gl2paintengineex/glgc_shader_source.h +++ /dev/null @@ -1,290 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GLGC_SHADER_SOURCE_H -#define GLGC_SHADER_SOURCE_H - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(OpenGL) - - -static const char* qglslImageVertexShader = "\ - attribute highp vec4 inputVertex; \ - attribute lowp vec2 textureCoord; \ - uniform highp mat4 pmvMatrix; \ - varying lowp vec2 fragTextureCoord; \ - void main(void) \ - {\ - gl_Position = pmvMatrix * inputVertex;\ - fragTextureCoord = textureCoord; \ - }"; - -static const char* qglslImageFragmentShader = "\ - varying lowp vec2 fragTextureCoord;\ - uniform sampler2D textureSampler;\ - uniform lowp float opacity; \ - void main(void) \ - {\ - gl_FragColor = texture2D(textureSampler, fragTextureCoord) * opacity; \ - }"; - -static const char* qglslTextFragmentShader = "\ - varying lowp vec2 fragTextureCoord;\ - uniform mediump vec4 fragmentColor;\ - uniform sampler2D textureSampler;\ - void main(void) \ - {\ - highp vec4 tex = texture2D(textureSampler, fragTextureCoord); \ - tex = fragmentColor * tex.r; \ - gl_FragColor = tex; \ - }"; - -static const char* qglslDefaultVertexShader = "\ - attribute highp vec4 inputVertex;\ - uniform highp mat4 pmvMatrix;\ - void main(void)\ - {\ - gl_Position = pmvMatrix * inputVertex;\ - }"; - -static const char* qglslSimpleFragmentShader = "\ - void main (void)\ - {\ - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\ - }"; - - -/**** FRAGMENT SHADER MAIN FUNCTIONS ****/ -// NOTE: Currently, the engine assumes brushes return colors already in pre-multiplied -// format. However, this may change if we add support for non-premultiplied - -static const char* qglslNoOpacityFragmentShaderMain = "\n\ - mediump vec4 brush();\ - void main (void)\ - {\ - gl_FragColor = brush();\ - }\n"; - -static const char* qglslFragmentShaderMain = "\n\ - mediump vec4 brush();\ - uniform lowp float opacity; \ - void main (void)\ - {\ - gl_FragColor = brush() * opacity;\ - }\n"; - - - -/**** BRUSH SHADERS ****/ - -// This should never actually be used -static const char* qglslNoBrushFragmentShader = "\n\ - mediump vec4 brush() { \ - discard; \ - return vec4(1.0, 0.8, 0.8, 1.0);\ - }\n"; - -// Solid Fill Brush -static const char* qglslSolidBrushFragmentShader = "\n\ - uniform mediump vec4 fragmentColor; \ - mediump vec4 brush() { \ - return fragmentColor;\ - }\n"; - -// Texture Brush -static const char* qglslTextureBrushVertexShader = "\ - attribute highp vec4 inputVertex; \ - uniform highp mat4 pmvMatrix; \ - uniform mediump vec2 halfViewportSize; \ - uniform mediump vec2 invertedTextureSize; \ - uniform mediump mat3 brushTransform; \ - varying mediump vec2 texCoords; \ - void main(void) { \ - gl_Position = pmvMatrix * inputVertex;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ - texCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ - texCoords.y = -texCoords.y; \ - }"; - -static const char* qglslTextureBrushFragmentShader = "\n\ - varying mediump vec2 texCoords;\ - uniform sampler2D brushTexture;\ - mediump vec4 brush() { \ - return texture2D(brushTexture, texCoords); \ - }\n"; - - -// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125 -static const char* qglslPatternBrushVertexShader = "\ - attribute highp vec4 inputVertex; \ - uniform highp mat4 pmvMatrix; \ - uniform mediump vec2 halfViewportSize; \ - uniform mediump vec2 invertedTextureSize; \ - uniform mediump mat3 brushTransform; \ - varying mediump vec2 texCoords; \ - void main(void) { \ - gl_Position = pmvMatrix * inputVertex;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ - texCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \ - texCoords.y = -texCoords.y; \ - }"; - -static const char* qglslPatternBrushFragmentShader = "\n\ - uniform sampler2D brushTexture;\ - uniform lowp vec4 patternColor; \ - varying mediump vec2 texCoords;\ - mediump vec4 brush() { \ - return patternColor * texture2D(brushTexture, texCoords).r; \ - }\n"; - - -// Linear Gradient Brush -static const char* qglslLinearGradientBrushVertexShader = "\ - attribute highp vec4 inputVertex; \ - uniform highp mat4 pmvMatrix; \ - uniform mediump vec2 halfViewportSize; \ - uniform highp vec3 linearData; \ - uniform mediump mat3 brushTransform; \ - varying mediump float index ; \ - void main() { \ - gl_Position = pmvMatrix * inputVertex;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ - index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \ - }"; - -static const char* qglslLinearGradientBrushFragmentShader = "\n\ - uniform sampler2D brushTexture; \ - varying mediump float index; \ - mediump vec4 brush() { \ - mediump vec2 val = vec2(index, 0.5); \ - return texture2D(brushTexture, val); \ - }\n"; - - -static const char* qglslRadialGradientBrushVertexShader = "\ - attribute highp vec4 inputVertex;\ - uniform highp mat4 pmvMatrix;\ - uniform mediump vec2 halfViewportSize; \ - uniform highp mat3 brushTransform; \ - uniform highp vec2 fmp; \ - varying highp float b; \ - varying highp vec2 A; \ - void main(void) \ - {\ - gl_Position = pmvMatrix * inputVertex;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ - A = hTexCoords.xy * invertedHTexCoordsZ; \ - b = 2.0 * fmp * (A.x + A.y); \ -\ - }"; - -static const char* qglslRadialGradientBrushFragmentShader = "\n\ - uniform sampler2D brushTexture; \ - uniform highp float fmp2_m_radius2; \ - uniform highp float inverse_2_fmp2_m_radius2; \ - varying highp float b; \ - varying highp vec2 A; \ -\ - mediump vec4 brush() { \ - highp float c = -dot(A, A); \ - highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \ - return texture2D(brushTexture, val); \ - }\n"; - -static const char* qglslConicalGradientBrushVertexShader = "\ - attribute highp vec4 inputVertex;\ - uniform highp mat4 pmvMatrix;\ - uniform mediump vec2 halfViewportSize; \ - uniform highp mat3 brushTransform; \ - varying highp vec2 A; \ - void main(void)\ - {\ - gl_Position = pmvMatrix * inputVertex;\ - gl_Position.xy = gl_Position.xy / gl_Position.w; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ - gl_Position.w = invertedHTexCoordsZ; \ - A = hTexCoords.xy * invertedHTexCoordsZ; \ - }"; - -static const char* qglslConicalGradientBrushFragmentShader = "\n\ - #define INVERSE_2PI 0.1591549430918953358 \n\ - uniform sampler2D brushTexture; \ - uniform mediump float angle; \ - varying highp vec2 A; \ - mediump vec4 brush() { \ - if (abs(A.y) == abs(A.x)) \ - A.y += 0.002; \ - highp float t = (atan2(-A.y, A.x) + angle) * INVERSE_2PI; \ - return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \ - }\n"; - - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // GLGC_SHADER_SOURCE_H diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 1086430..ea01604 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -40,12 +40,20 @@ ****************************************************************************/ #include "qglengineshadermanager_p.h" +#include "qglengineshadersource_p.h" #if defined(QT_DEBUG) #include #endif +const char* QGLEngineShaderManager::qglEngineShaderSourceCode[] = { + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0 +}; + QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) : ctx(context), shaderProgNeedsChanging(true), @@ -58,6 +66,77 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) currentShaderProg(0) { memset(compiledShaders, 0, sizeof(compiledShaders)); + +/* + Rather than having the shader source array statically initialised, it is initialised + here instead. This is to allow new shader names to be inserted or existing names moved + around without having to change the order of the glsl strings. It is hoped this will + make future hard-to-find runtime bugs more obvious and generally give more solid code. +*/ + static bool qglEngineShaderSourceCodePopulated = false; + if (!qglEngineShaderSourceCodePopulated) { + + const char** code = qglEngineShaderSourceCode; // shortcut + + code[SimpleVertexShader] = qglslSimpleVertexShader; + code[MainVertexShader] = qglslMainVertexShader; + code[MainWithTexCoordsVertexShader] = qglslMainWithTexCoordsVertexShader; + + code[PositionOnlyVertexShader] = qglslPositionOnlyVertexShader; + code[PositionWithPatternBrushVertexShader] = qglslPositionWithPatternBrushVertexShader; + code[PositionWithLinearGradientBrushVertexShader] = qglslPositionWithLinearGradientBrushVertexShader; + code[PositionWithConicalGradientBrushVertexShader] = qglslPositionWithConicalGradientBrushVertexShader; + code[PositionWithRadialGradientBrushVertexShader] = qglslPositionWithRadialGradientBrushVertexShader; + code[PositionWithTextureBrushVertexShader] = qglslPositionWithTextureBrushVertexShader; + code[AffinePositionWithPatternBrushVertexShader] = qglslAffinePositionWithPatternBrushVertexShader; + code[AffinePositionWithLinearGradientBrushVertexShader] = qglslAffinePositionWithLinearGradientBrushVertexShader; + code[AffinePositionWithConicalGradientBrushVertexShader] = qglslAffinePositionWithConicalGradientBrushVertexShader; + code[AffinePositionWithRadialGradientBrushVertexShader] = qglslAffinePositionWithRadialGradientBrushVertexShader; + code[AffinePositionWithTextureBrushVertexShader] = qglslAffinePositionWithTextureBrushVertexShader; + + code[MainFragmentShader_CMO] = qglslMainFragmentShader_CMO; + code[MainFragmentShader_CM] = qglslMainFragmentShader_CM; + code[MainFragmentShader_MO] = qglslMainFragmentShader_MO; + code[MainFragmentShader_M] = qglslMainFragmentShader_M; + code[MainFragmentShader_CO] = qglslMainFragmentShader_CO; + code[MainFragmentShader_C] = qglslMainFragmentShader_C; + code[MainFragmentShader_O] = qglslMainFragmentShader_O; + code[MainFragmentShader] = qglslMainFragmentShader; + + code[ImageSrcFragmentShader] = qglslImageSrcFragmentShader; + code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader; + code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader; + code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader; + code[PatternBrushSrcFragmentShader] = qglslPatternBrushSrcFragmentShader; + code[LinearGradientBrushSrcFragmentShader] = qglslLinearGradientBrushSrcFragmentShader; + code[RadialGradientBrushSrcFragmentShader] = qglslRadialGradientBrushSrcFragmentShader; + code[ConicalGradientBrushSrcFragmentShader] = qglslConicalGradientBrushSrcFragmentShader; + + code[MaskFragmentShader] = qglslMaskFragmentShader; + code[RgbMaskFragmentShader] = ""; //### + code[RgbMaskWithGammaFragmentShader] = ""; //### + + code[MultiplyCompositionModeFragmentShader] = ""; //### + code[ScreenCompositionModeFragmentShader] = ""; //### + code[OverlayCompositionModeFragmentShader] = ""; //### + code[DarkenCompositionModeFragmentShader] = ""; //### + code[LightenCompositionModeFragmentShader] = ""; //### + code[ColorDodgeCompositionModeFragmentShader] = ""; //### + code[ColorBurnCompositionModeFragmentShader] = ""; //### + code[HardLightCompositionModeFragmentShader] = ""; //### + code[SoftLightCompositionModeFragmentShader] = ""; //### + code[DifferenceCompositionModeFragmentShader] = ""; //### + code[ExclusionCompositionModeFragmentShader] = ""; //### + +#if defined(QT_DEBUG) + // Check that all the elements have been filled: + for (int i = 0; i < TotalShaderCount; ++i) { + if (qglEngineShaderSourceCode[i] == 0) + qCritical() << "qglEngineShaderSourceCode: Missing shader in element" << i; + } +#endif + qglEngineShaderSourceCodePopulated = true; + } } QGLEngineShaderManager::~QGLEngineShaderManager() @@ -303,15 +382,6 @@ void QGLEngineShaderManager::useCorrectShaderProg() } } -/* - QGLShader* mainVertexShader; - QGLShader* positionVertexShader; - QGLShader* mainFragShader; - QGLShader* srcPixelFragShader; - QGLShader* maskFragShader; // Can be null for no mask - QGLShader* compositionFragShader; // Can be null for GL-handled mode - QGLShaderProgram* program; -*/ // Shader program not found in cache, create it now. requiredProgram.program = new QGLShaderProgram(ctx, this); requiredProgram.program->addShader(requiredProgram.mainVertexShader); diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index fe30a70..38c1cff 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -375,8 +375,9 @@ private: QGLShader* compiledShaders[TotalShaderCount]; void compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type); -}; + static const char* qglEngineShaderSourceCode[TotalShaderCount]; +}; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h new file mode 100644 index 0000000..945c56c --- /dev/null +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -0,0 +1,385 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#ifndef QGL_ENGINE_SHADER_SOURCE_H +#define QGL_ENGINE_SHADER_SOURCE_H + +#include "qglengineshadermanager_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(OpenGL) + + +static const char* const qglslSimpleVertexShader = "\ + attribute highp vec4 inputVertex;\ + uniform highp mat4 pmvMatrix;\ + void main(void)\ + {\ + gl_Position = pmvMatrix * inputVertex;\ + }"; + +static const char* const qglslMainVertexShader = "\ + void setPosition();\ + void main(void)\ + {\ + setPosition();\ + }"; + +static const char* const qglslMainWithTexCoordsVertexShader = "\ + attribute lowp vec2 textureCoord; \ + varying lowp vec2 fragTextureCoord; \ + void setPosition();\ + void main(void) \ + {\ + setPosition();\ + fragTextureCoord = textureCoord; \ + }"; + + +static const char* const qglslPositionOnlyVertexShader = "\ + attribute highp vec4 inputVertex;\ + uniform highp mat4 pmvMatrix;\ + void setPosition(void)\ + {\ + gl_Position = pmvMatrix * inputVertex;\ + }"; + + +// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125 +static const char* const qglslPositionWithPatternBrushVertexShader = "\ + attribute highp vec4 inputVertex; \ + uniform highp mat4 pmvMatrix; \ + uniform mediump vec2 halfViewportSize; \ + uniform mediump vec2 invertedTextureSize; \ + uniform mediump mat3 brushTransform; \ + varying mediump vec2 patternTexCoords; \ + void setPosition(void) { \ + gl_Position = pmvMatrix * inputVertex;\ + gl_Position.xy = gl_Position.xy / gl_Position.w; \ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ + gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ + gl_Position.w = invertedHTexCoordsZ; \ + patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \ + patternTexCoords.y = -patternTexCoords.y; \ + }"; + +static const char* const qglslAffinePositionWithPatternBrushVertexShader + = qglslPositionWithPatternBrushVertexShader; + +static const char* const qglslPatternBrushSrcFragmentShader = "\ + uniform sampler2D brushTexture;\ + uniform lowp vec4 patternColor; \ + varying mediump vec2 patternTexCoords;\ + lowp vec4 srcPixel() { \ + return patternColor * texture2D(brushTexture, patternTexCoords).r; \ + }\n"; + + +// Linear Gradient Brush +static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\ + attribute highp vec4 inputVertex; \ + uniform highp mat4 pmvMatrix; \ + uniform mediump vec2 halfViewportSize; \ + uniform highp vec3 linearData; \ + uniform highp mat3 brushTransform; \ + varying mediump float index ; \ + void setPosition() { \ + gl_Position = pmvMatrix * inputVertex;\ + gl_Position.xy = gl_Position.xy / gl_Position.w; \ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ + gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ + gl_Position.w = invertedHTexCoordsZ; \ + index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \ + }"; + +static const char* const qglslAffinePositionWithLinearGradientBrushVertexShader + = qglslPositionWithLinearGradientBrushVertexShader; + +static const char* const qglslLinearGradientBrushSrcFragmentShader = "\ + uniform sampler2D brushTexture; \ + varying mediump float index; \ + lowp vec4 srcPixel() { \ + mediump vec2 val = vec2(index, 0.5); \ + return texture2D(brushTexture, val); \ + }\n"; + + +// Conical Gradient Brush +static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\ + attribute highp vec4 inputVertex;\ + uniform highp mat4 pmvMatrix;\ + uniform mediump vec2 halfViewportSize; \ + uniform highp mat3 brushTransform; \ + varying highp vec2 A; \ + void setPosition(void)\ + {\ + gl_Position = pmvMatrix * inputVertex;\ + gl_Position.xy = gl_Position.xy / gl_Position.w; \ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ + gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ + gl_Position.w = invertedHTexCoordsZ; \ + A = hTexCoords.xy * invertedHTexCoordsZ; \ + }"; + +static const char* const qglslAffinePositionWithConicalGradientBrushVertexShader + = qglslPositionWithConicalGradientBrushVertexShader; + +static const char* const qglslConicalGradientBrushSrcFragmentShader = "\ + #define INVERSE_2PI 0.1591549430918953358 \n\ + uniform sampler2D brushTexture; \ + uniform mediump float angle; \ + varying highp vec2 A; \ + lowp vec4 srcPixel() { \ + if (abs(A.y) == abs(A.x)) \ + A.y += 0.002; \ + highp float t = (atan2(-A.y, A.x) + angle) * INVERSE_2PI; \ + return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \ + }"; + + +// Radial Gradient Brush +static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\ + attribute highp vec4 inputVertex;\ + uniform highp mat4 pmvMatrix;\ + uniform mediump vec2 halfViewportSize; \ + uniform highp mat3 brushTransform; \ + uniform highp vec2 fmp; \ + varying highp float b; \ + varying highp vec2 A; \ + void setPosition(void) \ + {\ + gl_Position = pmvMatrix * inputVertex;\ + gl_Position.xy = gl_Position.xy / gl_Position.w; \ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ + gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ + gl_Position.w = invertedHTexCoordsZ; \ + A = hTexCoords.xy * invertedHTexCoordsZ; \ + b = 2.0 * fmp * (A.x + A.y); \ + }"; + +static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader + = qglslPositionWithRadialGradientBrushVertexShader; + +static const char* const qglslRadialGradientBrushSrcFragmentShader = "\ + uniform sampler2D brushTexture; \ + uniform highp float fmp2_m_radius2; \ + uniform highp float inverse_2_fmp2_m_radius2; \ + varying highp float b; \ + varying highp vec2 A; \ + lowp vec4 srcPixel() { \ + highp float c = -dot(A, A); \ + highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \ + return texture2D(brushTexture, val); \ + }"; + + +// Texture Brush +static const char* const qglslPositionWithTextureBrushVertexShader = "\ + attribute highp vec4 inputVertex; \ + uniform highp mat4 pmvMatrix; \ + uniform mediump vec2 halfViewportSize; \ + uniform mediump vec2 invertedTextureSize; \ + uniform mediump mat3 brushTransform; \ + varying mediump vec2 textureTexCoords; \ + void setPosition(void) { \ + gl_Position = pmvMatrix * inputVertex;\ + gl_Position.xy = gl_Position.xy / gl_Position.w; \ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ + gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ + gl_Position.w = invertedHTexCoordsZ; \ + textureTexCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ + textureTexCoords.y = -textureTexCoords.y; \ + }"; + +static const char* const qglslAffinePositionWithTextureBrushVertexShader + = qglslPositionWithTextureBrushVertexShader; + +static const char* const qglslTextureBrushSrcFragmentShader = "\ + varying mediump vec2 textureTexCoords; \ + uniform sampler2D brushTexture; \ + lowp vec4 srcPixel() { \ + return texture2D(brushTexture, textureTexCoords); \ + }"; + + +// Solid Fill Brush +static const char* const qglslSolidBrushSrcFragmentShader = "\ + uniform lowp vec4 fragmentColor; \ + lowp vec4 srcPixel() { \ + return fragmentColor; \ + }"; + +static const char* const qglslImageSrcFragmentShader = "\ + varying highp vec2 texCoord; \ + uniform sampler2D textureSampler; \ + lowp vec4 srcPixel() { \ + return texture2D(textureSampler, texCoord); \ + }"; + +static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\ + varying highp vec2 texCoord; \ + uniform sampler2D textureSampler; \ + lowp vec4 srcPixel() { \ + lowp vec4 sample = texture2D(textureSampler, texCoord); \ + sample.rgb = sample.rgb * sample.a; \ + return sample; \ + }"; + + +static const char* const qglslMainFragmentShader_CMO = "\ + uniform lowp float globalOpacity; \ + lowp vec4 srcPixel(); \ + lowp vec4 applyMask(lowp vec4); \ + lowp vec4 compose(lowp vec4); \ + void main() { \ + gl_FragColor = compose(applyMask(srcPixel()*globalOpacity)); \ + }"; + +static const char* const qglslMainFragmentShader_CM = "\ + lowp vec4 srcPixel(); \ + lowp vec4 applyMask(lowp vec4); \ + lowp vec4 compose(lowp vec4); \ + void main() { \ + gl_FragColor = compose(applyMask(srcPixel())); \ + }"; + +static const char* const qglslMainFragmentShader_MO = "\ + uniform lowp float globalOpacity; \ + lowp vec4 srcPixel(); \ + lowp vec4 applyMask(lowp vec4); \ + void main() { \ + gl_FragColor = applyMask(srcPixel()*globalOpacity); \ + }"; + +static const char* const qglslMainFragmentShader_M = "\ + lowp vec4 srcPixel(); \ + lowp vec4 applyMask(lowp vec4); \ + void main() { \ + gl_FragColor = applyMask(srcPixel()); \ + }"; + +static const char* const qglslMainFragmentShader_CO = "\ + uniform lowp float globalOpacity; \ + lowp vec4 srcPixel(); \ + lowp vec4 compose(lowp vec4); \ + void main() { \ + gl_FragColor = compose(srcPixel()*globalOpacity); \ + }"; + +static const char* const qglslMainFragmentShader_C = "\ + lowp vec4 srcPixel(); \ + lowp vec4 compose(lowp vec4); \ + void main() { \ + gl_FragColor = compose(srcPixel()); \ + }"; + +static const char* const qglslMainFragmentShader_O = "\ + uniform lowp float globalOpacity; \ + lowp vec4 srcPixel(); \ + void main() { \ + gl_FragColor = srcPixel()*globalOpacity; \ + }"; + +static const char* const qglslMainFragmentShader = "\ + lowp vec4 srcPixel(); \ + void main() { \ + gl_FragColor = srcPixel(); \ + }"; + + +static const char* const qglslMaskFragmentShader = "\ + varying highp vec2 texCoord;\ + uniform sampler2D maskTextureSampler;\ + lowp vec4 applyMask(lowp vec4 src) \ + {\ + lowp vec4 mask = texture2D(maskTextureSampler, texCoord); \ + return src * mask.a; \ + }"; + +/* + Left to implement: + RgbMaskFragmentShader, + RgbMaskWithGammaFragmentShader, + + MultiplyCompositionModeFragmentShader, + ScreenCompositionModeFragmentShader, + OverlayCompositionModeFragmentShader, + DarkenCompositionModeFragmentShader, + LightenCompositionModeFragmentShader, + ColorDodgeCompositionModeFragmentShader, + ColorBurnCompositionModeFragmentShader, + HardLightCompositionModeFragmentShader, + SoftLightCompositionModeFragmentShader, + DifferenceCompositionModeFragmentShader, + ExclusionCompositionModeFragmentShader, +*/ + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // GLGC_SHADER_SOURCE_H diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 1527f2d..8cf0e37 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -51,7 +51,7 @@ SOURCES += qgl.cpp \ gl2paintengineex/qglengineshadermanager_p.h \ gl2paintengineex/qgl2pexvertexarray_p.h \ gl2paintengineex/qpaintengineex_opengl2_p.h \ - gl2paintengineex/glgc_shader_source.h + gl2paintengineex/qglengineshadersource_p.h #} -- cgit v0.12 From a241ebac49f01ba0e26a177f1aadbd18c7e9cae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 16 Apr 2009 10:55:12 +0200 Subject: Use FBOs as pixmap backend in GL graphics system. We now use FBOs to implement render-to-pixmap for the GL pixmap backend. A multisample FBO is used for rendering, and is then blitted onto a non-multisample FBO dynamically bound to the relevant texture. Reviewed-by: Tom --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 38 +++- src/opengl/qgl.cpp | 56 ++++- src/opengl/qgl.h | 2 +- src/opengl/qgl_p.h | 8 +- src/opengl/qglframebufferobject.cpp | 16 +- src/opengl/qpixmapdata_gl.cpp | 236 +++++++++++++++------ src/opengl/qpixmapdata_gl_p.h | 19 +- src/opengl/qwindowsurface_gl.cpp | 34 ++- 8 files changed, 311 insertions(+), 98 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index e166b54..fe70020 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -175,6 +175,8 @@ public: // Clipping & state stuff stolen from QOpenGLPaintEngine: void updateDepthClip(); uint use_system_clip : 1; + + QPaintEngine *last_engine; }; @@ -616,7 +618,6 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) const QPointF* const points = reinterpret_cast(path.points()); - // Check to see if there's any hints if (path.shape() == QVectorPath::RectangleHint) { QGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y()); @@ -1034,6 +1035,14 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) qt_resolve_version_1_3_functions(d->ctx); qt_resolve_glsl_extensions(d->ctx); + d->last_engine = d->ctx->d_ptr->active_engine; + d->ctx->d_ptr->active_engine = this; + + if (d->last_engine) { + QGL2PaintEngineEx *engine = static_cast(d->last_engine); + static_cast(engine->d_ptr)->transferMode(DefaultMode); + } + if (!d->shaderManager) d->shaderManager = new QGLPEXShaderManager(d->ctx); @@ -1054,6 +1063,19 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->use_system_clip = !systemClip().isEmpty(); glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + + QGLPixmapData *source = d->drawable.copyOnBegin(); + if (source) { + d->transferMode(ImageDrawingMode); + + source->bind(); + + glDisable(GL_BLEND); + + QRect rect(0, 0, source->width(), source->height()); + d->drawTexture(QRectF(rect), QRectF(rect), rect.size()); + } updateClipRegion(QRegion(), Qt::NoClip); return true; @@ -1067,6 +1089,20 @@ bool QGL2PaintEngineEx::end() d->transferMode(DefaultMode); d->drawable.swapBuffers(); d->drawable.doneCurrent(); + d->ctx->d_ptr->active_engine = d->last_engine; + + if (d->last_engine) { + QGL2PaintEngineEx *engine = static_cast(d->last_engine); + QGL2PaintEngineExPrivate *p = static_cast(engine->d_ptr); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + + glViewport(0, 0, p->width, p->height); + engine->setState(engine->state()); + p->updateDepthClip(); + } + return false; } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index fc11d90..32531e7 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1295,6 +1295,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) eglContext = 0; #endif pbo = 0; + fbo = 0; crWin = false; initDone = false; sharing = false; @@ -1303,6 +1304,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) version_flags_cached = false; version_flags = QGLFormat::OpenGL_Version_None; current_fbo = 0; + active_engine = 0; } QGLContext* QGLContext::currentCtx = 0; @@ -1313,12 +1315,8 @@ QGLContext* QGLContext::currentCtx = 0; QGLFramebufferObject::toImage() */ -QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha) +static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha) { - QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32); - int w = size.width(); - int h = size.height(); - glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { // OpenGL gives RGBA; Qt wants ARGB uint *p = (uint*)img.bits(); @@ -1341,7 +1339,27 @@ QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB img = img.rgbSwapped(); } - return img.mirrored(); + img = img.mirrored(); +} + +QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha) +{ + QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32); + int w = size.width(); + int h = size.height(); + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); + convertFromGLImage(img, w, h, alpha_format, include_alpha); + return img; +} + +QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha) +{ + QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32); + int w = size.width(); + int h = size.height(); + glGetTexImage(qt_gl_preferredTextureTarget(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); + convertFromGLImage(img, w, h, alpha_format, include_alpha); + return img; } // returns the highest number closest to v, which is a power of 2 @@ -4235,6 +4253,15 @@ void QGLDrawable::setDevice(QPaintDevice *pdev) #ifdef Q_WS_QWS wsurf = 0; #endif + + if (pdev->devType() == QInternal::Pixmap) { + QPixmapData *data = static_cast(pdev)->pixmapData(); + Q_ASSERT(data->classId() == QPixmapData::OpenGLClass); + pixmapData = static_cast(data); + + fbo = pixmapData->fbo(); + } + if (pdev->devType() == QInternal::Widget) widget = static_cast(pdev); else if (pdev->devType() == QInternal::Pbuffer) @@ -4261,7 +4288,9 @@ void QGLDrawable::swapBuffers() void QGLDrawable::makeCurrent() { - if (widget) + if (pixmapData) + pixmapData->beginPaint(); + else if (widget) widget->makeCurrent(); else if (buffer) buffer->makeCurrent(); @@ -4274,9 +4303,18 @@ void QGLDrawable::makeCurrent() } } +QGLPixmapData *QGLDrawable::copyOnBegin() const +{ + if (!pixmapData || pixmapData->isUninitialized()) + return 0; + return pixmapData; +} + void QGLDrawable::doneCurrent() { - if (fbo && !wasBound) + if (pixmapData) + pixmapData->endPaint(); + else if (fbo && !wasBound) fbo->release(); } @@ -4285,6 +4323,8 @@ QSize QGLDrawable::size() const if (widget) { return QSize(widget->d_func()->glcx->device()->width(), widget->d_func()->glcx->device()->height()); + } else if (pixmapData) { + return pixmapData->size(); } else if (buffer) { return buffer->size(); } else if (fbo) { diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 32fbce2..19d779a 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -372,8 +372,8 @@ private: friend QGLContextPrivate *qt_phonon_get_dptr(const QGLContext *); #endif friend class QGLFramebufferObject; -#ifdef Q_WS_WIN friend class QGLFramebufferObjectPrivate; +#ifdef Q_WS_WIN friend bool qt_resolve_GLSL_functions(QGLContext *ctx); friend bool qt_createGLSLProgram(QGLContext *ctx, GLuint &program, const char *shader_src, GLuint &shader); #endif diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 8ab73d8..51c07b5 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -60,6 +60,7 @@ #include "QtCore/qthreadstorage.h" #include "QtCore/qhash.h" #include "private/qwidget_p.h" +#include "private/qpixmapdata_gl_p.h" #ifndef QT_OPENGL_ES_1_CL #define q_vertexType float @@ -238,6 +239,7 @@ public: QGLFormat glFormat; QGLFormat reqFormat; GLuint pbo; + GLuint fbo; uint valid : 1; uint sharing : 1; @@ -255,6 +257,7 @@ public: GLint max_texture_size; GLuint current_fbo; + QPaintEngine *active_engine; #ifdef Q_WS_WIN static inline QGLExtensionFuncs& qt_get_extension_funcs(const QGLContext *ctx) { return ctx->d_ptr->extensionFuncs; } @@ -289,7 +292,7 @@ class QGLWindowSurface; class QGLDrawable { public: QGLDrawable() : widget(0), buffer(0), fbo(0) - , wsurf(0) + , wsurf(0), pixmapData(0) {} void setDevice(QPaintDevice *pdev); void swapBuffers(); @@ -303,6 +306,8 @@ public: QGLContext *context() const; bool autoFillBackground() const; + QGLPixmapData *copyOnBegin() const; + private: bool wasBound; QGLWidget *widget; @@ -313,6 +318,7 @@ private: #else QGLWindowSurface *wsurf; #endif + QGLPixmapData *pixmapData; }; // GL extension definitions diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 61d0f85..f86205a 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -475,7 +475,7 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At fbo_attachment = QGLFramebufferObject::NoAttachment; } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); if (!valid) { if (color_buffer) glDeleteRenderbuffersEXT(1, &color_buffer); @@ -825,18 +825,17 @@ bool QGLFramebufferObject::release() return false; Q_D(QGLFramebufferObject); QGL_FUNC_CONTEXT; - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - d->valid = d->checkFramebufferStatus(); d->bound = false; + const QGLContext *context = QGLContext::currentContext(); - if (d->valid && context) { + if (context) { // Restore the previous setting for stacked framebuffer objects. context->d_ptr->current_fbo = d->previous_fbo; - if (d->previous_fbo) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, d->previous_fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, d->previous_fbo); d->previous_fbo = 0; } - return d->valid; + + return true; } /*! @@ -1148,8 +1147,7 @@ void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const Q tx0, ty0, tx1, ty1, buffers, filter); - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); } QT_END_NAMESPACE diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index ec71fa6..0656880 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qpixmap.h" +#include "qglframebufferobject.h" #include @@ -48,6 +49,12 @@ #include #include +#if 1 || defined(QT_OPENGL_ES_2) +#include +#else +#include +#endif + QT_BEGIN_NAMESPACE extern QGLWidget* qt_gl_share_widget(); @@ -89,48 +96,16 @@ private: QGLContext *m_ctx; }; -void qt_gl_convertFromGLImage(QImage *img) -{ - const int w = img->width(); - const int h = img->height(); - - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - uint *p = (uint*)img->bits(); - uint *end = p + w*h; - - while (p < end) { - uint a = *p << 24; - *p = (*p >> 8) | a; - p++; - } - - *img = img->mirrored(); - } else { - // mirror image - uint *data = (uint *)img->bits(); - - const int mid = h/2; - - for (int y = 0; y < mid; ++y) { - uint *p = data + y * w; - uint *end = p + w; - uint *q = data + (h - y - 1) * w; - - while (p < end) - qSwap(*p++, *q++); - } - } -} - - static int qt_gl_pixmap_serial = 0; QGLPixmapData::QGLPixmapData(PixelType type) : QPixmapData(type, OpenGLClass) , m_width(0) , m_height(0) + , m_renderFbo(0) + , m_textureId(0) + , m_engine(0) , m_ctx(0) - , m_texture(0) , m_dirty(false) { setSerialNumber(++qt_gl_pixmap_serial); @@ -138,10 +113,11 @@ QGLPixmapData::QGLPixmapData(PixelType type) QGLPixmapData::~QGLPixmapData() { - if (m_texture && qt_gl_share_widget()) { - QGLShareContextScope ctx(qt_gl_share_widget()->context()); - glDeleteTextures(1, &m_texture); - } + QGLWidget *shareWidget = qt_gl_share_widget(); + if (!shareWidget) + return; + QGLShareContextScope ctx(shareWidget->context()); + glDeleteTextures(1, &m_textureId); } bool QGLPixmapData::isValid() const @@ -166,6 +142,12 @@ void QGLPixmapData::resize(int width, int height) m_width = width; m_height = height; + if (m_textureId) { + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + glDeleteTextures(1, &m_textureId); + m_textureId = 0; + } + m_source = QImage(); m_dirty = isValid(); setSerialNumber(++qt_gl_pixmap_serial); @@ -184,24 +166,30 @@ void QGLPixmapData::ensureCreated() const const GLenum format = qt_gl_preferredTextureFormat(); const GLenum target = qt_gl_preferredTextureTarget(); - if (!m_texture) - glGenTextures(1, &m_texture); - - glBindTexture(target, m_texture); + if (!m_textureId) { + glGenTextures(1, &m_textureId); + glBindTexture(target, m_textureId); + glTexImage2D(target, 0, GL_RGBA, m_width, m_height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + } - if (m_source.isNull()) { - glTexImage2D(target, 0, GL_RGBA, m_width, m_height, 0, format, GL_UNSIGNED_BYTE, 0); - } else { + if (!m_source.isNull()) { const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, format); - glBindTexture(target, m_texture); - glTexImage2D(target, 0, GL_RGBA, m_width, m_height, 0, format, - GL_UNSIGNED_BYTE, tx.bits()); + glBindTexture(target, m_textureId); + glTexSubImage2D(target, 0, 0, 0, m_width, m_height, format, + GL_UNSIGNED_BYTE, tx.bits()); - m_source = QImage(); + if (useFramebufferObjects()) + m_source = QImage(); } } +QGLFramebufferObject *QGLPixmapData::fbo() const +{ + return m_renderFbo; +} + void QGLPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags) { @@ -220,6 +208,17 @@ bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect) return false; } +void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect) +{ + if (data->classId() != QPixmapData::OpenGLClass) { + QPixmapData::copy(data, rect); + return; + } + + // can be optimized to do a framebuffer blit or similar ... + QPixmapData::copy(data, rect); +} + void QGLPixmapData::fill(const QColor &color) { if (!isValid()) @@ -246,7 +245,9 @@ QImage QGLPixmapData::toImage() const if (!isValid()) return QImage(); - if (!m_source.isNull()) + if (m_renderFbo) + return m_renderFbo->toImage().copy(0, m_renderFbo->height() - m_height, m_width, m_height); + else if (!m_source.isNull()) return m_source; else if (m_dirty) return QImage(m_width, m_height, QImage::Format_ARGB32_Premultiplied); @@ -254,21 +255,84 @@ QImage QGLPixmapData::toImage() const ensureCreated(); QGLShareContextScope ctx(qt_gl_share_widget()->context()); - QImage img(m_width, m_height, QImage::Format_ARGB32_Premultiplied); + extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); + glBindTexture(qt_gl_preferredTextureTarget(), m_textureId); + return qt_gl_read_texture(QSize(m_width, m_height), true, true); +} - GLenum format = qt_gl_preferredTextureFormat(); - GLenum target = qt_gl_preferredTextureTarget(); +struct TextureBuffer +{ + QGLFramebufferObject *fbo; + QGL2PaintEngineEx *engine; +}; - glBindTexture(target, m_texture); -#ifndef QT_OPENGL_ES - glGetTexImage(target, 0, format, GL_UNSIGNED_BYTE, img.bits()); -#else - // XXX - cannot download textures this way on OpenGL/ES. -#endif +static QVector textureBufferStack; +static int currentTextureBuffer = 0; - qt_gl_convertFromGLImage(&img); +void QGLPixmapData::beginPaint() +{ + if (!isValid()) + return; - return img; + m_renderFbo->bind(); +} + +void QGLPixmapData::endPaint() +{ + if (!isValid()) + return; + + const QGLContext *share_ctx = qt_gl_share_widget()->context(); + QGLShareContextScope ctx(share_ctx); + + ensureCreated(); + + if (!ctx->d_ptr->fbo) + glGenFramebuffersEXT(1, &ctx->d_ptr->fbo); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + qt_gl_preferredTextureTarget(), m_textureId, 0); + + const int x0 = 0; + const int x1 = m_width; + const int y0 = 0; + const int y1 = m_height; + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); + + glDisable(GL_SCISSOR_TEST); + + glBlitFramebufferEXT(x0, y0, x1, y1, + x0, y0, x1, y1, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + + m_renderFbo->release(); + + --currentTextureBuffer; + + m_renderFbo = 0; + m_engine = 0; +} + +static TextureBuffer createTextureBuffer(const QSize &size, QGL2PaintEngineEx *engine = 0) +{ + TextureBuffer buffer; + QGLFramebufferObjectFormat fmt; + fmt.setAttachment(QGLFramebufferObject::CombinedDepthStencil); + fmt.setSamples(4); + + buffer.fbo = new QGLFramebufferObject(size, fmt); + buffer.engine = engine ? engine : new QGL2PaintEngineEx; + + return buffer; +} + +bool QGLPixmapData::useFramebufferObjects() +{ + return QGLFramebufferObject::hasOpenGLFramebufferObjects() + && QGLFramebufferObject::hasOpenGLFramebufferBlit(); } QPaintEngine* QGLPixmapData::paintEngine() const @@ -276,23 +340,59 @@ QPaintEngine* QGLPixmapData::paintEngine() const if (!isValid()) return 0; - m_source = toImage(); - m_dirty = true; + if (m_engine) + return m_engine; + else if (!useFramebufferObjects()) { + m_dirty = true; + + if (m_source.size() != size()) + m_source = QImage(size(), QImage::Format_ARGB32_Premultiplied); + return m_source.paintEngine(); + } - return m_source.paintEngine(); + extern QGLWidget* qt_gl_share_widget(); + + if (!QGLContext::currentContext()) + qt_gl_share_widget()->makeCurrent(); + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + + if (textureBufferStack.size() <= currentTextureBuffer) { + textureBufferStack << createTextureBuffer(size()); + } else { + QSize sz = textureBufferStack.at(currentTextureBuffer).fbo->size(); + if (sz.width() < m_width || sz.height() < m_height) { + if (sz.width() < m_width) + sz.setWidth(qMax(m_width, qRound(sz.width() * 1.5))); + if (sz.height() < m_height) + sz.setHeight(qMax(m_height, qRound(sz.height() * 1.5))); + delete textureBufferStack.at(currentTextureBuffer).fbo; + textureBufferStack[currentTextureBuffer] = + createTextureBuffer(sz, textureBufferStack.at(currentTextureBuffer).engine); + qDebug() << "Creating new pixmap texture buffer:" << sz; + } + } + + m_renderFbo = textureBufferStack.at(currentTextureBuffer).fbo; + m_engine = textureBufferStack.at(currentTextureBuffer).engine; + + ++currentTextureBuffer; + + return m_engine; } GLuint QGLPixmapData::bind() const { ensureCreated(); - glBindTexture(qt_gl_preferredTextureTarget(), m_texture); - return m_texture; + + GLuint id = m_textureId; + glBindTexture(qt_gl_preferredTextureTarget(), id); + return id; } GLuint QGLPixmapData::textureId() const { ensureCreated(); - return m_texture; + return m_textureId; } extern int qt_defaultDpiX(); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 97f4959..b1b31f7 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE class QPaintEngine; +class QGLFramebufferObject; class QGLPixmapData : public QPixmapData { @@ -72,6 +73,7 @@ public: void resize(int width, int height); void fromImage(const QImage &image, Qt::ImageConversionFlags flags); + void copy(const QPixmapData *data, const QRect &rect); bool scroll(int dx, int dy, const QRect &rect); @@ -87,6 +89,17 @@ public: void ensureCreated() const; + bool isUninitialized() const { return m_dirty && m_source.isNull(); } + + QSize size() const { return QSize(m_width, m_height); } + int width() const { return m_width; } + int height() const { return m_height; } + + QGLFramebufferObject *fbo() const; + + void beginPaint(); + void endPaint(); + protected: int metric(QPaintDevice::PaintDeviceMetric metric) const; @@ -94,11 +107,15 @@ private: QGLPixmapData(const QGLPixmapData &other); QGLPixmapData &operator=(const QGLPixmapData &other); + static bool useFramebufferObjects(); + int m_width; int m_height; + mutable QGLFramebufferObject *m_renderFbo; + mutable uint m_textureId; + mutable QPaintEngine *m_engine; mutable QGLContext *m_ctx; - mutable GLuint m_texture; mutable bool m_dirty; mutable QImage m_source; }; diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index c9d23d1..e0078bb 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -100,8 +100,8 @@ QGLGraphicsSystem::QGLGraphicsSystem() int i = 0; int spec[16]; spec[i++] = GLX_RGBA; -#if 0 spec[i++] = GLX_DOUBLEBUFFER; +#if 0 spec[i++] = GLX_DEPTH_SIZE; spec[i++] = 8; spec[i++] = GLX_STENCIL_SIZE; @@ -433,19 +433,35 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & size = parent->size(); } - ctx->makeCurrent(); -#ifdef Q_WS_MAC - ctx->updatePaintDevice(); -#endif - glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); if (d_ptr->fbo && QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) { - QGLFramebufferObject::blitFramebuffer(0, rect, d_ptr->fbo, rect); - d_ptr->fbo->bind(); + const int h = d_ptr->fbo->height(); + + const int x0 = rect.left(); + const int x1 = rect.left() + rect.width(); + const int y0 = h - (rect.top() + rect.height()); + const int y1 = h - rect.top(); + + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + + glBlitFramebufferEXT(x0, y0, x1, y1, + x0, y0, x1, y1, + GL_COLOR_BUFFER_BIT, + GL_NEAREST); + + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); } else { - if (d_ptr->fbo) + glDisable(GL_DEPTH_TEST); + + if (d_ptr->fbo) { d_ptr->fbo->release(); + } else { + ctx->makeCurrent(); +#ifdef Q_WS_MAC + ctx->updatePaintDevice(); +#endif + } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); -- cgit v0.12 From 33957a2fee921742769e89ce6af348d182d183b2 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 16 Apr 2009 17:57:00 +0200 Subject: Don't seg-fault when the shader prog is in the cache --- src/opengl/gl2paintengineex/qglengineshadermanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index ea01604..1253414 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -211,6 +211,7 @@ QGLShaderProgram* QGLEngineShaderManager::simpleProgram() void QGLEngineShaderManager::useCorrectShaderProg() { QGLEngineShaderProg requiredProgram; + requiredProgram.program = 0; // Choose vertex shader main function QGLEngineShaderManager::ShaderName mainVertexShaderName = InvalidShaderName; @@ -375,7 +376,7 @@ void QGLEngineShaderManager::useCorrectShaderProg() && (prog.srcPixelFragShader == requiredProgram.srcPixelFragShader) && (prog.compositionFragShader == requiredProgram.compositionFragShader) ) { - currentShaderProg = requiredProgram.program; + currentShaderProg = prog.program; currentShaderProg->enable(); shaderProgNeedsChanging = false; return; -- cgit v0.12 From fc1e97177f6ff9369fc6b14c66e5d0526741d3e7 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 16 Apr 2009 17:59:49 +0200 Subject: Make fillRect() with a QBrush(Qt::NoBrush) a noop --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index f1918c8..80f0b1d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -804,6 +804,9 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QGL2PaintEngineEx); + if (brush.style() == Qt::NoBrush) + return; + d->setBrush(&brush); d->fill(path); d->setBrush(&(state()->brush)); // reset back to the state's brush -- cgit v0.12 From b3f0d6e31c6897b1701de28d51980a81fb3e778f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 17 Apr 2009 10:04:08 +0200 Subject: Correctly handle using GL pixmaps that still have an active engine. In the case where a GL pixmap is used when there it still has an active engine we need to ensure that the pixmap has been flushed from the render FBO first. The newly added QGLPixmapData::copyBackFromRenderFbo() handles this. In addition, because several GL 2 paint engines can be active on the same context at the same time, we can't make any assumptions and need to call the newly added QGL2PaintEngineEx::ensureCreated() in the beginning of any state-dependent paint engine function. QGL2PaintEngineEx::ensureCreated() correctly transfers control to the current engine if a different engine is active. Running lance with -pixmap and -graphicssystem opengl works correctly with the GL pixmap backend now. --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 47 +++++++++++++++++++++- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 3 +- src/opengl/qgl.cpp | 6 ++- src/opengl/qpixmapdata_gl.cpp | 43 ++++++++++++++------ src/opengl/qpixmapdata_gl_p.h | 7 +++- 5 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index fe70020..8bf3182 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -805,6 +805,7 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QGL2PaintEngineEx); + ensureActive(); d->setBrush(&brush); d->fill(path); d->setBrush(&(state()->brush)); // reset back to the state's brush @@ -814,6 +815,7 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) { Q_D(QGL2PaintEngineEx); + ensureActive(); if (pen.style() == Qt::NoPen) return; @@ -832,7 +834,6 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) d->setBrush(&(state()->brush)); } else return QPaintEngineEx::stroke(path, pen); - } void QGL2PaintEngineEx::penChanged() @@ -887,6 +888,7 @@ void QGL2PaintEngineEx::transformChanged() void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src) { Q_D(QGL2PaintEngineEx); + ensureActive(); d->transferMode(ImageDrawingMode); QGLContext *ctx = d->ctx; @@ -905,6 +907,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const Qt::ImageConversionFlags) { Q_D(QGL2PaintEngineEx); + ensureActive(); d->transferMode(ImageDrawingMode); QGLContext *ctx = d->ctx; @@ -921,6 +924,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem) { Q_D(QGL2PaintEngineEx); + ensureActive(); QOpenGLPaintEngineState *s = state(); const QTextItemInt &ti = static_cast(textItem); @@ -974,6 +978,9 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte const QImage &image = cache->image(); int margin = cache->glyphMargin(); + if (image.isNull()) + return; + ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); @@ -1085,6 +1092,16 @@ bool QGL2PaintEngineEx::end() { Q_D(QGL2PaintEngineEx); QGLContext *ctx = d->ctx; + if (ctx->d_ptr->active_engine != this) { + QGL2PaintEngineEx *engine = static_cast(d->last_engine); + if (engine) { + QGL2PaintEngineExPrivate *p = static_cast(engine->d_ptr); + p->transferMode(DefaultMode); + p->drawable.doneCurrent(); + } + d->drawable.makeCurrent(); + } + glUseProgram(0); d->transferMode(DefaultMode); d->drawable.swapBuffers(); @@ -1106,6 +1123,31 @@ bool QGL2PaintEngineEx::end() return false; } +void QGL2PaintEngineEx::ensureActive() +{ + Q_D(QGL2PaintEngineEx); + QGLContext *ctx = d->ctx; + + if (isActive() && ctx->d_ptr->active_engine != this) { + QGL2PaintEngineEx *engine = static_cast(ctx->d_ptr->active_engine); + if (engine) { + QGL2PaintEngineExPrivate *p = static_cast(engine->d_ptr); + p->transferMode(DefaultMode); + p->drawable.doneCurrent(); + } + d->drawable.makeCurrent(); + + ctx->d_ptr->active_engine = this; + + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + + glViewport(0, 0, d->width, d->height); + setState(state()); + d->updateDepthClip(); + } +} + /////////////////////////////////// State/Clipping stolen from QOpenGLPaintEngine ////////////////////////////////////////// @@ -1246,6 +1288,7 @@ void QGL2PaintEngineExPrivate::updateDepthClip() Q_Q(QGL2PaintEngineEx); + q->ensureActive(); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); @@ -1305,7 +1348,7 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) QOpenGLPaintEngineState *old_state = state(); const bool needsDepthClipUpdate = !old_state || s->clipEnabled != old_state->clipEnabled - || s->clipEnabled && s->clipRegion != old_state->clipRegion; + || (s->clipEnabled && s->clipRegion != old_state->clipRegion); QPaintEngineEx::setState(s); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 10e5337..b31f685 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -80,6 +80,8 @@ public: bool begin(QPaintDevice *device); bool end(); + void ensureActive(); + virtual void fill(const QVectorPath &path, const QBrush &brush); virtual void stroke(const QVectorPath &path, const QPen &pen); virtual void clip(const QVectorPath &path, Qt::ClipOperation op); @@ -102,7 +104,6 @@ public: Type type() const { return OpenGL; } - // State stuff is just for clipping and ripped off from QGLPaintEngine void setState(QPainterState *s); QPainterState *createState(QPainterState *orig) const; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 64048f2..d1cf35d 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4289,6 +4289,8 @@ void QGLDrawable::swapBuffers() if (widget) { if (widget->autoBufferSwap()) widget->swapBuffers(); + } else if (pixmapData) { + pixmapData->swapBuffers(); } else { glFlush(); } @@ -4297,7 +4299,7 @@ void QGLDrawable::swapBuffers() void QGLDrawable::makeCurrent() { if (pixmapData) - pixmapData->beginPaint(); + pixmapData->makeCurrent(); else if (widget) widget->makeCurrent(); else if (buffer) @@ -4321,7 +4323,7 @@ QGLPixmapData *QGLDrawable::copyOnBegin() const void QGLDrawable::doneCurrent() { if (pixmapData) - pixmapData->endPaint(); + pixmapData->doneCurrent(); else if (fbo && !wasBound) fbo->release(); } diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 0656880..1c5056d 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -246,13 +246,13 @@ QImage QGLPixmapData::toImage() const return QImage(); if (m_renderFbo) - return m_renderFbo->toImage().copy(0, m_renderFbo->height() - m_height, m_width, m_height); + copyBackFromRenderFbo(true); else if (!m_source.isNull()) return m_source; else if (m_dirty) return QImage(m_width, m_height, QImage::Format_ARGB32_Premultiplied); - - ensureCreated(); + else + ensureCreated(); QGLShareContextScope ctx(qt_gl_share_widget()->context()); extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); @@ -269,15 +269,7 @@ struct TextureBuffer static QVector textureBufferStack; static int currentTextureBuffer = 0; -void QGLPixmapData::beginPaint() -{ - if (!isValid()) - return; - - m_renderFbo->bind(); -} - -void QGLPixmapData::endPaint() +void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const { if (!isValid()) return; @@ -308,6 +300,16 @@ void QGLPixmapData::endPaint() GL_COLOR_BUFFER_BIT, GL_NEAREST); + if (keepCurrentFboBound) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_ctx->d_ptr->current_fbo); +} + +void QGLPixmapData::swapBuffers() +{ + if (!isValid()) + return; + + copyBackFromRenderFbo(false); m_renderFbo->release(); --currentTextureBuffer; @@ -316,6 +318,18 @@ void QGLPixmapData::endPaint() m_engine = 0; } +void QGLPixmapData::makeCurrent() +{ + if (isValid() && m_renderFbo) + m_renderFbo->bind(); +} + +void QGLPixmapData::doneCurrent() +{ + if (isValid() && m_renderFbo) + m_renderFbo->release(); +} + static TextureBuffer createTextureBuffer(const QSize &size, QGL2PaintEngineEx *engine = 0) { TextureBuffer buffer; @@ -382,7 +396,10 @@ QPaintEngine* QGLPixmapData::paintEngine() const GLuint QGLPixmapData::bind() const { - ensureCreated(); + if (m_renderFbo) + copyBackFromRenderFbo(true); + else + ensureCreated(); GLuint id = m_textureId; glBindTexture(qt_gl_preferredTextureTarget(), id); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index b1b31f7..7dda653 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -97,8 +97,9 @@ public: QGLFramebufferObject *fbo() const; - void beginPaint(); - void endPaint(); + void makeCurrent(); + void doneCurrent(); + void swapBuffers(); protected: int metric(QPaintDevice::PaintDeviceMetric metric) const; @@ -107,6 +108,8 @@ private: QGLPixmapData(const QGLPixmapData &other); QGLPixmapData &operator=(const QGLPixmapData &other); + void copyBackFromRenderFbo(bool keepCurrentFboBound) const; + static bool useFramebufferObjects(); int m_width; -- cgit v0.12 From 0b37db60b856fd146727eb621c5447aff09ffc5a Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 17 Apr 2009 11:04:21 +0200 Subject: Fix GLSL warning & possible artifacts with radial gradients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Samuel Rødal --- src/opengl/gl2paintengineex/qglengineshadersource_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 945c56c..3aa1a36 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -215,7 +215,7 @@ static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\ gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ gl_Position.w = invertedHTexCoordsZ; \ A = hTexCoords.xy * invertedHTexCoordsZ; \ - b = 2.0 * fmp * (A.x + A.y); \ + b = 2.0 * dot(A, fmp); \ }"; static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader -- cgit v0.12 From 534f2575a19422cff06e27b46f65c6630da6ee7f Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 17 Apr 2009 11:18:21 +0200 Subject: Add a "shocking pink" shader for rendering into stencil buff If you see shocking pink in the rendering output, it's probably because the "simple" shader is in use but color writes have somehow been enabled. :-) --- .../gl2paintengineex/qglengineshadermanager.cpp | 26 ++++++++++++++++++++-- .../gl2paintengineex/qglengineshadermanager_p.h | 1 + .../gl2paintengineex/qglengineshadersource_p.h | 5 +++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 1253414..7c165ae 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -111,6 +111,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) code[LinearGradientBrushSrcFragmentShader] = qglslLinearGradientBrushSrcFragmentShader; code[RadialGradientBrushSrcFragmentShader] = qglslRadialGradientBrushSrcFragmentShader; code[ConicalGradientBrushSrcFragmentShader] = qglslConicalGradientBrushSrcFragmentShader; + code[ShockingPinkSrcFragmentShader] = qglslShockingPinkSrcFragmentShader; code[MaskFragmentShader] = qglslMaskFragmentShader; code[RgbMaskFragmentShader] = ""; //### @@ -131,12 +132,33 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) #if defined(QT_DEBUG) // Check that all the elements have been filled: for (int i = 0; i < TotalShaderCount; ++i) { - if (qglEngineShaderSourceCode[i] == 0) - qCritical() << "qglEngineShaderSourceCode: Missing shader in element" << i; + if (qglEngineShaderSourceCode[i] == 0) { + int enumIndex = staticMetaObject.indexOfEnumerator("ShaderName"); + QMetaEnum m = staticMetaObject.enumerator(enumIndex); + + qCritical() << "qglEngineShaderSourceCode: Source for" << m.valueToKey(i) + << "(shader" << i << ") missing!"; + } } #endif qglEngineShaderSourceCodePopulated = true; } + + // Compile up the simple shader: + simpleShaderProg = new QGLShaderProgram(ctx, this); + compileNamedShader(MainVertexShader, QGLShader::PartialVertexShader); + compileNamedShader(PositionOnlyVertexShader, QGLShader::PartialVertexShader); + compileNamedShader(MainFragmentShader, QGLShader::PartialFragmentShader); + compileNamedShader(ShockingPinkSrcFragmentShader, QGLShader::PartialFragmentShader); + simpleShaderProg->addShader(compiledShaders[MainVertexShader]); + simpleShaderProg->addShader(compiledShaders[PositionOnlyVertexShader]); + simpleShaderProg->addShader(compiledShaders[MainFragmentShader]); + simpleShaderProg->addShader(compiledShaders[ShockingPinkSrcFragmentShader]); + simpleShaderProg->link(); + if (!simpleShaderProg->isValid()) { + qCritical() << "Errors linking simple shader:" + << simpleShaderProg->errors(); + } } QGLEngineShaderManager::~QGLEngineShaderManager() diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 38c1cff..61a62dc 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -317,6 +317,7 @@ public: LinearGradientBrushSrcFragmentShader, RadialGradientBrushSrcFragmentShader, ConicalGradientBrushSrcFragmentShader, + ShockingPinkSrcFragmentShader, MaskFragmentShader, RgbMaskFragmentShader, diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 3aa1a36..d605b01 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -288,6 +288,11 @@ static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\ return sample; \ }"; +static const char* const qglslShockingPinkSrcFragmentShader = "\ + lowp vec4 srcPixel() { \ + return lowp vec4(0.98, 0.06, 0.75, 1.0); \ + }"; + static const char* const qglslMainFragmentShader_CMO = "\ uniform lowp float globalOpacity; \ -- cgit v0.12 From 4701bc6fa8fe47d5038ed0a86a4e6c0490c259fe Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 17 Apr 2009 12:00:08 +0200 Subject: Fix various issues with conical grad GLSL code - atan2 is just called atan in GLSL (which supports overloads) - varyings can't be modified in fragment shaders - #defines need to be on their own line --- src/opengl/gl2paintengineex/qglengineshadersource_p.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index d605b01..7557431 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -183,15 +183,17 @@ static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\ static const char* const qglslAffinePositionWithConicalGradientBrushVertexShader = qglslPositionWithConicalGradientBrushVertexShader; -static const char* const qglslConicalGradientBrushSrcFragmentShader = "\ +static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\ #define INVERSE_2PI 0.1591549430918953358 \n\ - uniform sampler2D brushTexture; \ + uniform sampler2D brushTexture; \n\ uniform mediump float angle; \ varying highp vec2 A; \ lowp vec4 srcPixel() { \ + highp float t; \ if (abs(A.y) == abs(A.x)) \ - A.y += 0.002; \ - highp float t = (atan2(-A.y, A.x) + angle) * INVERSE_2PI; \ + t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \ + else \ + t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \ return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \ }"; -- cgit v0.12 From 8027a669e31d2fc96f9ffdfc0771034571dd583e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 17 Apr 2009 12:33:52 +0200 Subject: Smudgy text in GL2 paint engine when drawing on non-integer offsets. Special-case TextDrawingMode in updateMatrix() as we know that we'll have a pure translating transform, and round the transform's dx and dy to avoid drawing on non-integer offsets. Task-number: 245806 Reviewed-by: Tom --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 60 ++++++++++++++-------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 8bf3182..19163a8 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -412,32 +412,45 @@ void QGL2PaintEngineExPrivate::updateMatrix() {0.0, 0.0, 0.0, 1.0} }; - // Use the (3x3) transform for the Model~View matrix: const QTransform& transform = q->state()->matrix; - GLfloat MV[4][4] = { - {transform.m11(), transform.m21(), 0.0, transform.dx()}, - {transform.m12(), transform.m22(), 0.0, transform.dy()}, - {0.0, 0.0, 1.0, 0.0}, - {transform.m13(), transform.m23(), 0.0, transform.m33()} - }; - // NOTE: OpenGL ES works with column-major matrices, so when we multiply the matrices, - // we also transpose them ready for GL. - for (int row = 0; row < 4; ++row) { - for (int col = 0; col < 4; ++col) { - pmvMatrix[col][row] = 0.0; + if (mode == TextDrawingMode) { + // Text drawing mode is only used for non-scaling transforms + for (int row = 0; row < 4; ++row) + for (int col = 0; col < 4; ++col) + pmvMatrix[col][row] = P[row][col]; + + pmvMatrix[3][0] += P[0][0] * qRound(transform.dx()); + pmvMatrix[3][1] += P[1][1] * qRound(transform.dy()); - // P[row][n] is 0.0 for n < row - for (int n = row; n < 4; ++n) - pmvMatrix[col][row] += P[row][n] * MV[n][col]; + inverseScale = 1; + } else { + // Use the (3x3) transform for the Model~View matrix: + GLfloat MV[4][4] = { + {transform.m11(), transform.m21(), 0.0, transform.dx()}, + {transform.m12(), transform.m22(), 0.0, transform.dy()}, + {0.0, 0.0, 1.0, 0.0}, + {transform.m13(), transform.m23(), 0.0, transform.m33()} + }; + + // NOTE: OpenGL ES works with column-major matrices, so when we multiply the matrices, + // we also transpose them ready for GL. + for (int row = 0; row < 4; ++row) { + for (int col = 0; col < 4; ++col) { + pmvMatrix[col][row] = 0.0; + + // P[row][n] is 0.0 for n < row + for (int n = row; n < 4; ++n) + pmvMatrix[col][row] += P[row][n] * MV[n][col]; + } } - } - // 1/10000 == 0.0001, so we have good enough res to cover curves - // that span the entire widget... - inverseScale = qMax(1 / qMax( qMax(qAbs(transform.m11()), qAbs(transform.m22())), - qMax(qAbs(transform.m12()), qAbs(transform.m21())) ), - qreal(0.0001)); + // 1/10000 == 0.0001, so we have good enough res to cover curves + // that span the entire widget... + inverseScale = qMax(1 / qMax( qMax(qAbs(transform.m11()), qAbs(transform.m22())), + qMax(qAbs(transform.m12()), qAbs(transform.m21())) ), + qreal(0.0001)); + } matrixDirty = false; @@ -554,6 +567,9 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); } + if (mode == TextDrawingMode) + matrixDirty = true; + if (newMode == TextDrawingMode) { glEnable(GL_BLEND); glActiveTexture(QT_BRUSH_TEXTURE_UNIT); @@ -566,6 +582,8 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) shaderManager->textShader()->use(); shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; + + matrixDirty = true; } if (newMode == ImageDrawingMode) { -- cgit v0.12 From 4b4d4b3d7ae4ad019963d957831c46daacba62f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 20 Apr 2009 12:23:48 +0200 Subject: Prevent copy back from FBO when initializing render FBO from texture. --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 2 +- src/opengl/qpixmapdata_gl.cpp | 6 +++--- src/opengl/qpixmapdata_gl_p.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 19163a8..d0f0ad6 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1094,7 +1094,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) if (source) { d->transferMode(ImageDrawingMode); - source->bind(); + source->bind(false); glDisable(GL_BLEND); diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 1c5056d..1fa5b47 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -301,7 +301,7 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const GL_NEAREST); if (keepCurrentFboBound) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_ctx->d_ptr->current_fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); } void QGLPixmapData::swapBuffers() @@ -394,9 +394,9 @@ QPaintEngine* QGLPixmapData::paintEngine() const return m_engine; } -GLuint QGLPixmapData::bind() const +GLuint QGLPixmapData::bind(bool copyBack) const { - if (m_renderFbo) + if (m_renderFbo && copyBack) copyBackFromRenderFbo(true); else ensureCreated(); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 7dda653..536f33d 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -82,7 +82,7 @@ public: QImage toImage() const; QPaintEngine* paintEngine() const; - GLuint bind() const; + GLuint bind(bool copyBack = true) const; GLuint textureId() const; bool isValidContext(const QGLContext *ctx) const; -- cgit v0.12 From 0c7348cbc5fbbd06ff6752d98e5a6506b8cb5ffa Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 20 Apr 2009 13:46:42 +0200 Subject: Refactor opacity handling & make drawImage/drawPixmap work again --- .../gl2paintengineex/qglengineshadermanager.cpp | 8 +- .../gl2paintengineex/qglengineshadermanager_p.h | 9 +- .../gl2paintengineex/qglengineshadersource_p.h | 28 ++--- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 139 ++++++++++----------- 4 files changed, 96 insertions(+), 88 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 7c165ae..15d4a9d 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -248,7 +248,7 @@ void QGLEngineShaderManager::useCorrectShaderProg() // varyings) and the source pixel (srcPixel) fragment shader function: QGLEngineShaderManager::ShaderName positionVertexShaderName = InvalidShaderName; QGLEngineShaderManager::ShaderName srcPixelFragShaderName = InvalidShaderName; - bool isAffine = transform.isAffine(); + bool isAffine = brushTransform.isAffine(); if ( (srcPixelType >= Qt::Dense1Pattern) && (srcPixelType <= Qt::DiagCrossPattern) ) { if (isAffine) positionVertexShaderName = AffinePositionWithPatternBrushVertexShader; @@ -413,6 +413,12 @@ void QGLEngineShaderManager::useCorrectShaderProg() requiredProgram.program->addShader(requiredProgram.srcPixelFragShader); requiredProgram.program->addShader(requiredProgram.maskFragShader); requiredProgram.program->addShader(requiredProgram.compositionFragShader); + + // We have to bind the vertex attribute names before the program is linked: + requiredProgram.program->bindAttributeLocation("inputVertex", QT_VERTEX_COORDS_ATTR); + if (useTextureCoords) + requiredProgram.program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); + requiredProgram.program->link(); if (!requiredProgram.program->isValid()) { QString error; diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 61a62dc..8fb0d5b 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -253,6 +253,9 @@ struct QGLEngineCachedShaderProg } */ +static const GLuint QT_VERTEX_COORDS_ATTR = 0; +static const GLuint QT_TEXTURE_COORDS_ATTR = 1; + class QGLEngineShaderManager : public QObject { Q_OBJECT; @@ -266,9 +269,9 @@ public: NonPremultipliedImageSrc = Qt::TexturePattern+2 }; - // There are optimisations we can do, depending on the transform: + // There are optimisations we can do, depending on the brush transform: // 1) May not have to apply perspective-correction - // 2) Can use lower precision for vertecies + // 2) Can use lower precision for matrix void optimiseForBrushTransform(const QTransform transform); void setSrcPixelType(Qt::BrushStyle); void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images @@ -360,7 +363,7 @@ private: bool shaderProgNeedsChanging; // Current state variables which influence the choice of shader: - QTransform transform; + QTransform brushTransform; int srcPixelType; bool useGlobalOpacity; MaskType maskType; diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 7557431..2c284cb 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -79,13 +79,13 @@ static const char* const qglslMainVertexShader = "\ }"; static const char* const qglslMainWithTexCoordsVertexShader = "\ - attribute lowp vec2 textureCoord; \ - varying lowp vec2 fragTextureCoord; \ + attribute lowp vec2 textureCoordArray; \ + varying lowp vec2 textureCoords; \ void setPosition();\ void main(void) \ {\ setPosition();\ - fragTextureCoord = textureCoord; \ + textureCoords = textureCoordArray; \ }"; @@ -243,7 +243,7 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\ uniform mediump vec2 halfViewportSize; \ uniform mediump vec2 invertedTextureSize; \ uniform mediump mat3 brushTransform; \ - varying mediump vec2 textureTexCoords; \ + varying mediump vec2 brushTextureCoords; \ void setPosition(void) { \ gl_Position = pmvMatrix * inputVertex;\ gl_Position.xy = gl_Position.xy / gl_Position.w; \ @@ -252,18 +252,18 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ gl_Position.xy = gl_Position.xy * invertedHTexCoordsZ; \ gl_Position.w = invertedHTexCoordsZ; \ - textureTexCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ - textureTexCoords.y = -textureTexCoords.y; \ + brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ + brushTextureCoords.y = -brushTextureCoords.y; \ }"; static const char* const qglslAffinePositionWithTextureBrushVertexShader = qglslPositionWithTextureBrushVertexShader; static const char* const qglslTextureBrushSrcFragmentShader = "\ - varying mediump vec2 textureTexCoords; \ + varying mediump vec2 brushTextureCoords; \ uniform sampler2D brushTexture; \ lowp vec4 srcPixel() { \ - return texture2D(brushTexture, textureTexCoords); \ + return texture2D(brushTexture, brushTextureCoords); \ }"; @@ -275,17 +275,17 @@ static const char* const qglslSolidBrushSrcFragmentShader = "\ }"; static const char* const qglslImageSrcFragmentShader = "\ - varying highp vec2 texCoord; \ - uniform sampler2D textureSampler; \ + varying highp vec2 textureCoords; \ + uniform sampler2D imageTexture; \ lowp vec4 srcPixel() { \ - return texture2D(textureSampler, texCoord); \ + return texture2D(imageTexture, textureCoords); \ }"; static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\ - varying highp vec2 texCoord; \ - uniform sampler2D textureSampler; \ + varying highp vec2 textureCoords; \ + uniform sampler2D imageTexture; \ lowp vec4 srcPixel() { \ - lowp vec4 sample = texture2D(textureSampler, texCoord); \ + lowp vec4 sample = texture2D(imageTexture, textureCoords); \ sample.rgb = sample.rgb * sample.a; \ return sample; \ }"; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 80f0b1d..c5ed6cc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -89,12 +89,13 @@ extern QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp enum EngineMode { ImageDrawingMode, TextDrawingMode, - DefaultMode + BrushDrawingMode }; -static const GLuint QT_VERTEX_COORDS_ATTR = 0; -static const GLuint QT_TEXTURE_COORDS_ATTR = 1; -static const GLuint QT_BRUSH_TEXTURE_UNIT = 0; +static const GLuint QT_BRUSH_TEXTURE_UNIT = 0; +static const GLuint QT_IMAGE_TEXTURE_UNIT = 0; //Can be the same as brush texture unit +static const GLuint QT_MASK_TEXTURE_UNIT = 1; +static const GLuint QT_BACKGROUND_TEXTURE_UNIT = 2; class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate { @@ -135,7 +136,7 @@ public: // ^ Calls drawVertexArrays to render into stencil buffer void cleanStencilBuffer(const QGLRect& area); - void prepareForDraw(); + void prepareForDraw(bool srcPixelsAreOpaque); inline void useSimpleShader(); inline QColor premultiplyColor(QColor c, GLfloat opacity); @@ -153,9 +154,7 @@ public: bool brushTextureDirty; bool brushUniformsDirty; bool simpleShaderMatrixUniformDirty; - bool brushShaderMatrixUniformDirty; - bool imageShaderMatrixUniformDirty; - bool textShaderMatrixUniformDirty; + bool shaderMatrixUniformDirty; bool stencilBuferDirty; const QBrush* currentBrush; // May not be the state's brush! @@ -190,7 +189,7 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform) { - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); + glActiveTexture(QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit? if (smoothPixmapTransform) { glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -270,6 +269,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() else updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, true); + glActiveTexture(QT_BRUSH_TEXTURE_UNIT); glBindTexture(GL_TEXTURE_2D, texId); } else if (style == Qt::TexturePattern) { @@ -291,17 +291,11 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() if (style == Qt::NoBrush) return; - GLfloat opacity = 1.0; - if (q->state()->opacity < 0.99f) - opacity = (GLfloat)q->state()->opacity; - bool setOpacity = true; - QTransform brushQTransform = currentBrush->transform(); if (style == Qt::SolidPattern) { - QColor col = premultiplyColor(currentBrush->color(), opacity); + QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); shaderManager->currentProgram()->setUniformValue("fragmentColor", col); - setOpacity = false; } else { // All other brushes have a transform and thus need the translation point: @@ -310,10 +304,9 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() if (style <= Qt::DiagCrossPattern) { translationPoint = q->state()->brushOrigin; - QColor col = premultiplyColor(currentBrush->color(), opacity); + QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); shaderManager->currentProgram()->setUniformValue("patternColor", col); - setOpacity = false; //So code below doesn't try to set the opacity uniform QVector2D halfViewportSize(width*0.5, height*0.5); shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize); @@ -387,9 +380,6 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() shaderManager->currentProgram()->setUniformValue("brushTransform", inv_matrix); shaderManager->currentProgram()->setUniformValue("brushTexture", QT_BRUSH_TEXTURE_UNIT); - - if (setOpacity) - shaderManager->currentProgram()->setUniformValue("opacity", opacity); } brushUniformsDirty = false; } @@ -439,9 +429,7 @@ void QGL2PaintEngineExPrivate::updateMatrix() // The actual data has been updated so both shader program's uniforms need updating simpleShaderMatrixUniformDirty = true; - brushShaderMatrixUniformDirty = true; - imageShaderMatrixUniformDirty = true; - textShaderMatrixUniformDirty = true; + shaderMatrixUniformDirty = true; } @@ -515,19 +503,13 @@ void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& s // qDebug("QGL2PaintEngineExPrivate::drawImage()"); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); - if (compositionModeDirty) - updateCompositionMode(); + // Setup for texture drawing + shaderManager->setSrcPixelType(QGLEngineShaderManager::ImageSrc); + shaderManager->setTextureCoordsEnabled(true); + prepareForDraw(false); // ### + transferMode(ImageDrawingMode); - if (matrixDirty) - updateMatrix(); - - if (imageShaderMatrixUniformDirty) { -// shaderManager->imageShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; - imageShaderMatrixUniformDirty = false; - } - -// if (q->state()->opacity < 0.99f) -// shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)q->state()->opacity; + shaderManager->currentProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); GLfloat dx = 1.0 / textureSize.width(); GLfloat dy = 1.0 / textureSize.height(); @@ -552,7 +534,7 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) if (newMode == TextDrawingMode) { glEnable(GL_BLEND); - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); +// glActiveTexture(QT_BRUSH_TEXTURE_UNIT); glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); @@ -565,28 +547,27 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) } if (newMode == ImageDrawingMode) { - // We have a shader specifically for drawPixmap/drawImage... -// shaderManager->imageShader()->use(); -// shaderManager->imageShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; -// shaderManager->imageShader()->uniforms()[QLatin1String("opacity")] = (GLfloat)1.0; - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticVertexCoordinateArray); glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticTextureCoordinateArray); - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); +// glActiveTexture(QT_BRUSH_TEXTURE_UNIT); } + // If we're switching to BrushDrawingMode, set the source pixel type to match the brush style: + if (newMode == BrushDrawingMode) + shaderManager->setSrcPixelType(currentBrush->style()); + mode = newMode; } void QGL2PaintEngineExPrivate::drawOutline(const QVectorPath& path) { - transferMode(DefaultMode); + transferMode(BrushDrawingMode); -// qDebug("QGL2PaintEngineExPrivate::drawOutline()"); + // Might need to call updateMatrix to re-calculate inverseScale if (matrixDirty) updateMatrix(); @@ -599,7 +580,7 @@ void QGL2PaintEngineExPrivate::drawOutline(const QVectorPath& path) vertexCoordinateArray.stops().last() += 1; } - prepareForDraw(); + prepareForDraw(currentBrush->isOpaque()); drawVertexArrays(vertexCoordinateArray, GL_LINE_STRIP); } @@ -607,24 +588,24 @@ void QGL2PaintEngineExPrivate::drawOutline(const QVectorPath& path) // Assumes everything is configured for the brush you want to use void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) { - transferMode(DefaultMode); + transferMode(BrushDrawingMode); + // Might need to call updateMatrix to re-calculate inverseScale if (matrixDirty) updateMatrix(); const QPointF* const points = reinterpret_cast(path.points()); - // Check to see if there's any hints if (path.shape() == QVectorPath::RectangleHint) { QGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y()); - prepareForDraw(); + prepareForDraw(currentBrush->isOpaque()); composite(rect); } else if (path.shape() == QVectorPath::EllipseHint) { vertexCoordinateArray.clear(); vertexCoordinateArray.addPath(path, inverseScale); - prepareForDraw(); + prepareForDraw(currentBrush->isOpaque()); drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); } else { @@ -637,7 +618,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) // Stencil the brush onto the dest buffer glStencilFunc(GL_NOTEQUAL, 0, 0xFFFF); // Pass if stencil buff value != 0 glEnable(GL_STENCIL_TEST); - prepareForDraw(); + prepareForDraw(currentBrush->isOpaque()); composite(vertexCoordinateArray.boundingRect()); glDisable(GL_STENCIL_TEST); @@ -717,34 +698,55 @@ void QGL2PaintEngineExPrivate::cleanStencilBuffer(const QGLRect& area) glDisable(GL_STENCIL_TEST); } -void QGL2PaintEngineExPrivate::prepareForDraw() +void QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) { - if (brushTextureDirty) + if (brushTextureDirty && mode != ImageDrawingMode) updateBrushTexture(); if (compositionModeDirty) updateCompositionMode(); + if (matrixDirty) + updateMatrix(); + + const bool stateHasOpacity = q->state()->opacity < 0.99f; + if ( (!srcPixelsAreOpaque || stateHasOpacity) && + q->state()->compositionMode() != QPainter::CompositionMode_Source) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); + + bool useGlobalOpacityUniform = stateHasOpacity; + if (stateHasOpacity && (mode != ImageDrawingMode)) { + // Using a brush + bool brushIsPattern = (currentBrush->style() >= Qt::Dense1Pattern) && + (currentBrush->style() <= Qt::DiagCrossPattern); + + if ((currentBrush->style() == Qt::SolidPattern) || brushIsPattern) + useGlobalOpacityUniform = false; // Global opacity handled by srcPixel shader + } + shaderManager->setUseGlobalOpacity(useGlobalOpacityUniform); + + + // If the shader program needs changing, we change it and mark all uniforms as dirty if (shaderManager->shaderProgramDirty()) { shaderManager->useCorrectShaderProg(); // The shader program has changed so mark all uniforms as dirty: brushUniformsDirty = true; - brushShaderMatrixUniformDirty = true; + shaderMatrixUniformDirty = true; } - if (brushUniformsDirty) + if (brushUniformsDirty && mode != ImageDrawingMode) updateBrushUniforms(); - if (brushShaderMatrixUniformDirty) { + if (shaderMatrixUniformDirty) { shaderManager->currentProgram()->setUniformValue("pmvMatrix", pmvMatrix); - brushShaderMatrixUniformDirty = false; + shaderMatrixUniformDirty = false; } - if ((q->state()->opacity < 0.99f) || !currentBrush->isOpaque()) - glEnable(GL_BLEND); - else - glDisable(GL_BLEND); + if (useGlobalOpacityUniform) + shaderManager->currentProgram()->setUniformValue("globalOpacity", (GLfloat)q->state()->opacity); } void QGL2PaintEngineExPrivate::composite(const QGLRect& boundingRect) @@ -863,7 +865,6 @@ void QGL2PaintEngineEx::opacityChanged() Q_D(QGL2PaintEngineEx); Q_ASSERT(d->shaderManager); - d->shaderManager->setUseGlobalOpacity(state()->opacity > 0.999); d->brushUniformsDirty = true; } @@ -986,10 +987,10 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte if (matrixDirty) updateMatrix(); - if (textShaderMatrixUniformDirty) { +// if (textShaderMatrixUniformDirty) { // shaderManager->textShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; - textShaderMatrixUniformDirty = false; - } +// textShaderMatrixUniformDirty = false; +// } QColor col = premultiplyColor(s->pen.color(), (GLfloat)s->opacity); // shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col; @@ -1032,7 +1033,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) QSize sz = d->drawable.size(); d->width = sz.width(); d->height = sz.height(); - d->mode = DefaultMode; + d->mode = BrushDrawingMode; qt_resolve_version_1_3_functions(d->ctx); qt_resolve_glsl_extensions(d->ctx); @@ -1067,7 +1068,7 @@ bool QGL2PaintEngineEx::end() Q_D(QGL2PaintEngineEx); QGLContext *ctx = d->ctx; glUseProgram(0); - d->transferMode(DefaultMode); + d->transferMode(BrushDrawingMode); d->drawable.swapBuffers(); d->drawable.doneCurrent(); return false; @@ -1285,9 +1286,7 @@ void QGL2PaintEngineEx::setState(QPainterState *s) d->brushTextureDirty = true; d->brushUniformsDirty = true; d->simpleShaderMatrixUniformDirty = true; - d->brushShaderMatrixUniformDirty = true; - d->imageShaderMatrixUniformDirty = true; - d->textShaderMatrixUniformDirty = true; + d->shaderMatrixUniformDirty = true; } QPainterState *QGL2PaintEngineEx::createState(QPainterState *orig) const -- cgit v0.12 From b2f319ccdd2b4fda28e3fdb2128be75c97da75ee Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 20 Apr 2009 13:57:42 +0200 Subject: Kill unused SimpleVertexShader & rename vertex coords array Rename inputVertex -> vertexCoordsArray to be more consistent with other vertex attribute array naming conventions. SimpleVertexShader has also been replaced with a combination of MainVertexShader & PositionOnlyVertexShader, so can be killed. --- .../gl2paintengineex/qglengineshadermanager.cpp | 1 - .../gl2paintengineex/qglengineshadermanager_p.h | 2 -- .../gl2paintengineex/qglengineshadersource_p.h | 32 ++++++++-------------- 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 15d4a9d..a4d8b77 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -78,7 +78,6 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) const char** code = qglEngineShaderSourceCode; // shortcut - code[SimpleVertexShader] = qglslSimpleVertexShader; code[MainVertexShader] = qglslMainVertexShader; code[MainWithTexCoordsVertexShader] = qglslMainWithTexCoordsVertexShader; diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 8fb0d5b..dec8f56 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -87,7 +87,6 @@ correction is needed and a simpler vertex shader can be used instead. So there are the following "main" vertex shaders: - qglslSimpleVertexShader qglslMainVertexShader qglslMainWithTexCoordsVertexShader @@ -287,7 +286,6 @@ public: QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers enum ShaderName { - SimpleVertexShader, MainVertexShader, MainWithTexCoordsVertexShader, diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 2c284cb..2da993a 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -63,14 +63,6 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) -static const char* const qglslSimpleVertexShader = "\ - attribute highp vec4 inputVertex;\ - uniform highp mat4 pmvMatrix;\ - void main(void)\ - {\ - gl_Position = pmvMatrix * inputVertex;\ - }"; - static const char* const qglslMainVertexShader = "\ void setPosition();\ void main(void)\ @@ -90,24 +82,24 @@ static const char* const qglslMainWithTexCoordsVertexShader = "\ static const char* const qglslPositionOnlyVertexShader = "\ - attribute highp vec4 inputVertex;\ + attribute highp vec4 vertexCoordsArray;\ uniform highp mat4 pmvMatrix;\ void setPosition(void)\ {\ - gl_Position = pmvMatrix * inputVertex;\ + gl_Position = pmvMatrix * vertexCoordsArray;\ }"; // Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125 static const char* const qglslPositionWithPatternBrushVertexShader = "\ - attribute highp vec4 inputVertex; \ + attribute highp vec4 vertexCoordsArray; \ uniform highp mat4 pmvMatrix; \ uniform mediump vec2 halfViewportSize; \ uniform mediump vec2 invertedTextureSize; \ uniform mediump mat3 brushTransform; \ varying mediump vec2 patternTexCoords; \ void setPosition(void) { \ - gl_Position = pmvMatrix * inputVertex;\ + gl_Position = pmvMatrix * vertexCoordsArray;\ gl_Position.xy = gl_Position.xy / gl_Position.w; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ @@ -132,14 +124,14 @@ static const char* const qglslPatternBrushSrcFragmentShader = "\ // Linear Gradient Brush static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\ - attribute highp vec4 inputVertex; \ + attribute highp vec4 vertexCoordsArray; \ uniform highp mat4 pmvMatrix; \ uniform mediump vec2 halfViewportSize; \ uniform highp vec3 linearData; \ uniform highp mat3 brushTransform; \ varying mediump float index ; \ void setPosition() { \ - gl_Position = pmvMatrix * inputVertex;\ + gl_Position = pmvMatrix * vertexCoordsArray;\ gl_Position.xy = gl_Position.xy / gl_Position.w; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ @@ -163,14 +155,14 @@ static const char* const qglslLinearGradientBrushSrcFragmentShader = "\ // Conical Gradient Brush static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\ - attribute highp vec4 inputVertex;\ + attribute highp vec4 vertexCoordsArray;\ uniform highp mat4 pmvMatrix;\ uniform mediump vec2 halfViewportSize; \ uniform highp mat3 brushTransform; \ varying highp vec2 A; \ void setPosition(void)\ {\ - gl_Position = pmvMatrix * inputVertex;\ + gl_Position = pmvMatrix * vertexCoordsArray;\ gl_Position.xy = gl_Position.xy / gl_Position.w; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ @@ -200,7 +192,7 @@ static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\ // Radial Gradient Brush static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\ - attribute highp vec4 inputVertex;\ + attribute highp vec4 vertexCoordsArray;\ uniform highp mat4 pmvMatrix;\ uniform mediump vec2 halfViewportSize; \ uniform highp mat3 brushTransform; \ @@ -209,7 +201,7 @@ static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\ varying highp vec2 A; \ void setPosition(void) \ {\ - gl_Position = pmvMatrix * inputVertex;\ + gl_Position = pmvMatrix * vertexCoordsArray;\ gl_Position.xy = gl_Position.xy / gl_Position.w; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ @@ -238,14 +230,14 @@ static const char* const qglslRadialGradientBrushSrcFragmentShader = "\ // Texture Brush static const char* const qglslPositionWithTextureBrushVertexShader = "\ - attribute highp vec4 inputVertex; \ + attribute highp vec4 vertexCoordsArray; \ uniform highp mat4 pmvMatrix; \ uniform mediump vec2 halfViewportSize; \ uniform mediump vec2 invertedTextureSize; \ uniform mediump mat3 brushTransform; \ varying mediump vec2 brushTextureCoords; \ void setPosition(void) { \ - gl_Position = pmvMatrix * inputVertex;\ + gl_Position = pmvMatrix * vertexCoordsArray;\ gl_Position.xy = gl_Position.xy / gl_Position.w; \ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ -- cgit v0.12 From 756d1f3f3b3f1c6c42e0e1afa4f090a6b2e18199 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 21 Apr 2009 15:37:47 +0200 Subject: Make text rendering work again on the GL2 engine - But now it can handle non-solid-color pens, the whole reason for the refactor in the first place. --- .../gl2paintengineex/qglengineshadersource_p.h | 9 +-- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 85 +++++++++++----------- 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 2da993a..f2facac 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -348,14 +348,13 @@ static const char* const qglslMainFragmentShader = "\ gl_FragColor = srcPixel(); \ }"; - static const char* const qglslMaskFragmentShader = "\ - varying highp vec2 texCoord;\ - uniform sampler2D maskTextureSampler;\ + varying highp vec2 textureCoords;\ + uniform sampler2D maskTexture;\ lowp vec4 applyMask(lowp vec4 src) \ {\ - lowp vec4 mask = texture2D(maskTextureSampler, texCoord); \ - return src * mask.a; \ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \ + return src * mask.r; \ }"; /* diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index c5ed6cc..63cdd87 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -122,11 +122,11 @@ public: void transferMode(EngineMode newMode); - void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize); - void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti); - + // fill, drawOutline, drawTexture & drawCachedGlyphs are the rendering entry points: void fill(const QVectorPath &path); void drawOutline(const QVectorPath& path); + void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize); + void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti); void drawVertexArrays(QGL2PEXVertexArray& vertexArray, GLenum primitive); // ^ draws whatever is in the vertex array @@ -189,7 +189,7 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform) { - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit? +// glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit? if (smoothPixmapTransform) { glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -249,7 +249,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() // Get the image data for the pattern QImage texImage = qt_imageForBrush(style, true); - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); + glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, true); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, true); } @@ -269,13 +269,13 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() else updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, true); - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); + glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); glBindTexture(GL_TEXTURE_2D, texId); } else if (style == Qt::TexturePattern) { const QPixmap& texPixmap = currentBrush->texture(); - glActiveTexture(QT_BRUSH_TEXTURE_UNIT); + glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); ctx->d_func()->bindTexture(texPixmap, GL_TEXTURE_2D, GL_RGBA, true); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, true); } @@ -500,14 +500,14 @@ static inline void setCoords(GLfloat *coords, const QGLRect &rect) void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize) { -// qDebug("QGL2PaintEngineExPrivate::drawImage()"); + transferMode(ImageDrawingMode); + updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); // Setup for texture drawing shaderManager->setSrcPixelType(QGLEngineShaderManager::ImageSrc); shaderManager->setTextureCoordsEnabled(true); prepareForDraw(false); // ### - transferMode(ImageDrawingMode); shaderManager->currentProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); @@ -533,17 +533,11 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) } if (newMode == TextDrawingMode) { - glEnable(GL_BLEND); -// glActiveTexture(QT_BRUSH_TEXTURE_UNIT); - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); - -// shaderManager->textShader()->use(); -// shaderManager->textShader()->uniforms()[QLatin1String("textureSampler")] = QT_BRUSH_TEXTURE_UNIT; } if (newMode == ImageDrawingMode) { @@ -552,14 +546,16 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticVertexCoordinateArray); glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, staticTextureCoordinateArray); - -// glActiveTexture(QT_BRUSH_TEXTURE_UNIT); } // If we're switching to BrushDrawingMode, set the source pixel type to match the brush style: - if (newMode == BrushDrawingMode) + if (newMode == BrushDrawingMode || newMode == TextDrawingMode) shaderManager->setSrcPixelType(currentBrush->style()); + // This needs to change when we implement high-quality anti-aliasing... + if (newMode != TextDrawingMode) + shaderManager->setMaskType(QGLEngineShaderManager::NoMask); + mode = newMode; } @@ -893,6 +889,7 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c d->transferMode(ImageDrawingMode); QGLContext *ctx = d->ctx; + glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true); //FIXME: we should use hasAlpha() instead, but that's SLOW at the moment @@ -911,6 +908,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const d->transferMode(ImageDrawingMode); QGLContext *ctx = d->ctx; + glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); if ((state()->opacity < 0.99f) || image.hasAlphaChannel()) @@ -930,9 +928,6 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem bool drawCached = true; - if (state()->pen.brush().style() != Qt::SolidPattern) - drawCached = false; - if (s->matrix.type() > QTransform::TxTranslate) drawCached = false; @@ -950,21 +945,33 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti) { + transferMode(TextDrawingMode); + Q_Q(QGL2PaintEngineEx); QOpenGLPaintEngineState *s = q->state(); - transferMode(TextDrawingMode); - QVarLengthArray positions; QVarLengthArray glyphs; QTransform matrix; matrix.translate(p.x(), p.y()); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); + QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat) : QFontEngineGlyphCache::Raster_A8; + GLenum maskFormat = GL_RGBA; + if (glyphType == QFontEngineGlyphCache::Raster_A8) { + shaderManager->setMaskType(QGLEngineShaderManager::PixelMask); +// maskFormat = GL_ALPHA; + } + else if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) + shaderManager->setMaskType(QGLEngineShaderManager::SubPixelMask); + //### TODO: Gamma correction + shaderManager->setTextureCoordsEnabled(true); + + QImageTextureGlyphCache *cache = (QImageTextureGlyphCache *) ti.fontEngine->glyphCache(glyphType, s->matrix); if (!cache) { @@ -977,23 +984,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte const QImage &image = cache->image(); int margin = cache->glyphMargin(); - ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); - - updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); - - if (compositionModeDirty) - updateCompositionMode(); - - if (matrixDirty) - updateMatrix(); - -// if (textShaderMatrixUniformDirty) { -// shaderManager->textShader()->uniforms()[QLatin1String("pmvMatrix")] = pmvMatrix; -// textShaderMatrixUniformDirty = false; -// } - - QColor col = premultiplyColor(s->pen.color(), (GLfloat)s->opacity); -// shaderManager->textShader()->uniforms()[QLatin1String("fragmentColor")] = col; GLfloat dx = 1.0 / image.width(); GLfloat dy = 1.0 / image.height(); @@ -1013,12 +1003,26 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte textureCoordinateArray.addRect(QRectF(c.x*dx, 1 - c.y*dy, c.w * dx, -c.h * dy)); } + + glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); + ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); + updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); + + QBrush pensBrush = q->state()->pen.brush(); + setBrush(&pensBrush); + + prepareForDraw(false); // Text always causes src pixels to be transparent + + shaderManager->currentProgram()->setUniformValue("maskTexture", QT_MASK_TEXTURE_UNIT); + if (vertexCoordinateArray.data() != oldVertexCoordinateDataPtr) glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data()); if (textureCoordinateArray.data() != oldTextureCoordinateDataPtr) glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray.data()); glDrawArrays(GL_TRIANGLES, 0, 6 * glyphs.size()); + + setBrush(&(q->state()->brush)); //### } bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) @@ -1068,7 +1072,6 @@ bool QGL2PaintEngineEx::end() Q_D(QGL2PaintEngineEx); QGLContext *ctx = d->ctx; glUseProgram(0); - d->transferMode(BrushDrawingMode); d->drawable.swapBuffers(); d->drawable.doneCurrent(); return false; -- cgit v0.12 From aa295fbfdae1a687bc7bd9f7f364721a35566828 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 22 Apr 2009 17:25:36 +0200 Subject: Change fragment shaders to apply the mask as the final step I.e. After composition, not before. --- src/opengl/gl2paintengineex/qglengineshadersource_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index f2facac..bf896b1 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -294,7 +294,7 @@ static const char* const qglslMainFragmentShader_CMO = "\ lowp vec4 applyMask(lowp vec4); \ lowp vec4 compose(lowp vec4); \ void main() { \ - gl_FragColor = compose(applyMask(srcPixel()*globalOpacity)); \ + gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \ }"; static const char* const qglslMainFragmentShader_CM = "\ @@ -302,7 +302,7 @@ static const char* const qglslMainFragmentShader_CM = "\ lowp vec4 applyMask(lowp vec4); \ lowp vec4 compose(lowp vec4); \ void main() { \ - gl_FragColor = compose(applyMask(srcPixel())); \ + gl_FragColor = applyMask(compose(srcPixel())); \ }"; static const char* const qglslMainFragmentShader_MO = "\ -- cgit v0.12 From 0df382c78aeaf74c161d753f04ae9a13e951c0a1 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 22 Apr 2009 17:35:26 +0200 Subject: Make optimiseForBrushTransform take a QTransform reference --- src/opengl/gl2paintengineex/qglengineshadermanager.cpp | 2 +- src/opengl/gl2paintengineex/qglengineshadermanager_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index a4d8b77..6e702e5 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -169,7 +169,7 @@ QGLEngineShaderManager::~QGLEngineShaderManager() -void QGLEngineShaderManager::optimiseForBrushTransform(const QTransform transform) +void QGLEngineShaderManager::optimiseForBrushTransform(const QTransform &transform) { Q_UNUSED(transform); // Currently ignored } diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index dec8f56..d3856fe 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -271,7 +271,7 @@ public: // There are optimisations we can do, depending on the brush transform: // 1) May not have to apply perspective-correction // 2) Can use lower precision for matrix - void optimiseForBrushTransform(const QTransform transform); + void optimiseForBrushTransform(const QTransform &transform); void setSrcPixelType(Qt::BrushStyle); void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images void setTextureCoordsEnabled(bool); // For images & text glyphs -- cgit v0.12 From 873aa5cb7542497dd4e98bcc145b479f32343b5e Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 22 Apr 2009 17:38:02 +0200 Subject: Make useCorrectShaderProg() return a bool again Returns true if it had to change the shader program so the engine knows it needs to clean the uniforms. --- src/opengl/gl2paintengineex/qglengineshadermanager.cpp | 16 ++++++++-------- src/opengl/gl2paintengineex/qglengineshadermanager_p.h | 3 +-- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 4 +--- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 6e702e5..3d8d34b 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -210,11 +210,6 @@ void QGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode) shaderProgNeedsChanging = true; //### } -bool QGLEngineShaderManager::shaderProgramDirty() -{ - return shaderProgNeedsChanging; -} - QGLShaderProgram* QGLEngineShaderManager::currentProgram() { return currentShaderProg; @@ -228,9 +223,13 @@ QGLShaderProgram* QGLEngineShaderManager::simpleProgram() -// Select & use the correct shader program using the current state -void QGLEngineShaderManager::useCorrectShaderProg() +// Select & use the correct shader program using the current state. +// Returns true if program needed changing. +bool QGLEngineShaderManager::useCorrectShaderProg() { + if (!shaderProgNeedsChanging) + return false; + QGLEngineShaderProg requiredProgram; requiredProgram.program = 0; @@ -400,7 +399,7 @@ void QGLEngineShaderManager::useCorrectShaderProg() currentShaderProg = prog.program; currentShaderProg->enable(); shaderProgNeedsChanging = false; - return; + return true; } } @@ -442,6 +441,7 @@ void QGLEngineShaderManager::useCorrectShaderProg() currentShaderProg->enable(); } shaderProgNeedsChanging = false; + return true; } void QGLEngineShaderManager::compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index d3856fe..e9e261f 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -279,8 +279,7 @@ public: void setMaskType(MaskType); void setCompositionMode(QPainter::CompositionMode); - bool shaderProgramDirty(); // returns true if the shader program needs to be changed - void useCorrectShaderProg(); + bool useCorrectShaderProg(); // returns true if the shader program needed to be changed QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 5a701aa..7dbdc32 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -741,9 +741,7 @@ void QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) // If the shader program needs changing, we change it and mark all uniforms as dirty - if (shaderManager->shaderProgramDirty()) { - shaderManager->useCorrectShaderProg(); - + if (shaderManager->useCorrectShaderProg()) { // The shader program has changed so mark all uniforms as dirty: brushUniformsDirty = true; shaderMatrixUniformDirty = true; -- cgit v0.12 From 6e0e3c7312bbceef69e61b745d88076224745a33 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 22 Apr 2009 17:39:55 +0200 Subject: Allow release builds again The list of shaders shouldn't change too much now. --- src/opengl/gl2paintengineex/qglengineshadermanager_p.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index e9e261f..b8b2745 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -350,8 +350,6 @@ public: #if defined (QT_DEBUG) Q_ENUMS(ShaderName); -#else -#error Release build not supported yet #endif -- cgit v0.12 From 89aa644baabd8a118a59cb367aca2adf1363564e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 23 Apr 2009 14:06:07 +0200 Subject: Remove old qglshader files from gl2paintengineex. --- src/opengl/gl2paintengineex/qglshader.cpp | 616 ------------------------------ src/opengl/gl2paintengineex/qglshader_p.h | 262 ------------- 2 files changed, 878 deletions(-) delete mode 100644 src/opengl/gl2paintengineex/qglshader.cpp delete mode 100644 src/opengl/gl2paintengineex/qglshader_p.h diff --git a/src/opengl/gl2paintengineex/qglshader.cpp b/src/opengl/gl2paintengineex/qglshader.cpp deleted file mode 100644 index ea4cae9..0000000 --- a/src/opengl/gl2paintengineex/qglshader.cpp +++ /dev/null @@ -1,616 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglshader_p.h" - - -// Windows needs to resolve OpenGL 2.0 function pointers for each context. The -// QGL OpenGL 2.0 functions are actually macros, which take a "ctx" parameter. -#define Q_CTX QGLContext* ctx = d->ctx; \ - if (!ctx) \ - return false; \ - ctx->makeCurrent(); \ - -#if !defined(QT_OPENGL_ES_2) -static const char *qglslDefines = "#define lowp\n#define mediump\n#define highp\n"; -#include "private/qgl_p.h" -#else -static const char *qglslDefines = ""; -#endif - - -class QGLShaderPrivate -{ -public: - QGLShaderPrivate() : shaderId(0), valid(false), ctx(0) {} - - GLuint shaderId; - QString source; - bool valid; - QGLShader::ShaderType type; - QGLContext* ctx; -}; - - -QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext* ctx) - : d_ptr(new QGLShaderPrivate) -{ - Q_D(QGLShader); - - if (!ctx) - ctx = QGLContext::currentContext(); - - if (!ctx) { - qWarning("QGLShader being created without a context"); - return; - } - - d->ctx = const_cast(ctx); - d->ctx->makeCurrent(); - - if (type == QGLShader::FragmentShader) - d->shaderId = glCreateShader(GL_FRAGMENT_SHADER); - else - d->shaderId = glCreateShader(GL_VERTEX_SHADER); - - if (d->shaderId == 0) { - qWarning("Error creating shader object"); - return; - } - - d->type = type; -} - -GLuint QGLShader::id() -{ - Q_D(QGLShader); - return d->shaderId; -} - -const QGLContext* QGLShader::context() -{ - Q_D(QGLShader); - return d->ctx; -} - -void QGLShader::clearSource() -{ - Q_D(QGLShader); - d->source.clear(); - d->valid = false; -} - -void QGLShader::addSource(const QLatin1String& newSource) -{ - Q_D(QGLShader); - d->source += newSource; - d->valid = false; -} - - -bool QGLShader::compile() -{ - Q_D(QGLShader); - - d->valid = false; - - if (d->source.size() == 0) - return false; - - const QByteArray src_ba = d->source.toAscii(); - const char* src[2]; - src[0] = qglslDefines; - src[1] = src_ba.constData(); - - - QGLContext *ctx = d->ctx; - glShaderSource(d->shaderId, 2, src, 0); - - glCompileShader(d->shaderId); - - GLint shaderCompiled; - glGetShaderiv(d->shaderId, GL_COMPILE_STATUS, &shaderCompiled); - if (!shaderCompiled) - return false; - - d->valid = true; - return true; -} - -bool QGLShader::isValid() -{ - Q_D(QGLShader); - return d->valid; -} - -QString QGLShader::log() -{ - Q_D(QGLShader); - - char* logData; - GLint logSize; - GLint logLength; - - QGLContext *ctx = d->ctx; - glGetShaderiv(d->shaderId, GL_INFO_LOG_LENGTH, &logSize); - - if (!logSize) - return QString(); - - logData = new char[logSize]; - glGetShaderInfoLog(d->shaderId, logSize, &logLength, logData); - QString result = QString::fromAscii(logData); - delete [] logData; - - return result; -} - - - - - - - - - - - - -class QGLShaderProgramPrivate -{ -public: - QGLShaderProgramPrivate() : valid(false), programId(0), ctx(0) {} - void populateVariableLists(); - - QVector shaders; - QGLUniformList uniforms; - QGLVertexAttributeList attributeArrays; - bool valid; - GLuint programId; - QGLContext* ctx; -}; - - - -void QGLShaderProgramPrivate::populateVariableLists() -{ - attributeArrays.clear(); - uniforms.clear(); - - int count; - int sizeOfNameBuff; - char* name; - GLint nameLength; - GLenum type; - GLint size; - GLint location; - - glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &count); - glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &sizeOfNameBuff); - name = new char[sizeOfNameBuff]; - - for (int i = 0; i < count; ++i) { - nameLength = -1; - glGetActiveAttrib(programId, i, sizeOfNameBuff, &nameLength, &size, &type, name); - if (nameLength == -1) - continue; - - location = glGetAttribLocation(programId, name); - attributeArrays.insert(QString::fromAscii(name), QGLVertexAttribute(type, location, ctx)); - } - - delete [] name; - - - glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &count); - glGetProgramiv(programId, GL_ACTIVE_UNIFORM_MAX_LENGTH, &sizeOfNameBuff); - - name = new char[sizeOfNameBuff]; - - for (int i = 0; i < count; ++i) { - nameLength = -1; - glGetActiveUniform(programId, i, sizeOfNameBuff, &nameLength, &size, &type, name); - if (nameLength == -1) - continue; - - location = glGetUniformLocation(programId, name); - uniforms.insert(QString::fromAscii(name), QGLUniform(type, location, ctx)); - } -} - - -QGLShaderProgram::QGLShaderProgram(const QGLContext* ctx) - : d_ptr(new QGLShaderProgramPrivate) -{ - Q_D(QGLShaderProgram); - if (!ctx) - ctx = QGLContext::currentContext(); - - if (!ctx) { - qWarning("QGLShaderProgram being created without a context"); - return; - } - - d->ctx = const_cast(ctx); - d->ctx->makeCurrent(); - - d->programId = glCreateProgram(); - - d->valid = false; -} - - -const QGLUniformList & QGLShaderProgram::uniforms() -{ - Q_D(QGLShaderProgram); - return const_cast(d->uniforms); -} - - -const QGLVertexAttributeList& QGLShaderProgram::vertexAttributes() -{ - Q_D(QGLShaderProgram); - return const_cast(d->attributeArrays); -} - - -bool QGLShaderProgram::addShader(QGLShader* newShader) -{ - Q_D(QGLShaderProgram); - if (!newShader || !d->ctx) - return false; - - if (newShader->context() != d->ctx) { - qWarning("Shader object's context does not match program's context"); - return false; - } - - if (!newShader->isValid()) - return false; - - QGLContext* ctx = d->ctx; - if (!ctx) - return false; - ctx->makeCurrent(); - - glAttachShader(d->programId, newShader->id()); - - d->shaders.append(newShader); - return true; -} - - -bool QGLShaderProgram::removeShader(QGLShader* oldShader) -{ - Q_D(QGLShaderProgram); - - int idx = d->shaders.indexOf(oldShader); - - if (idx == -1) - return false; - - d->shaders.remove(idx); - - QGLContext* ctx = d->ctx; - if (!ctx) - return false; - ctx->makeCurrent(); - - glDetachShader(d->programId, oldShader->id()); - return true; -} - - -bool QGLShaderProgram::removeAllShaders() -{ - Q_D(QGLShaderProgram); - - QGLContext* ctx = d->ctx; - if (!ctx) - return false; - ctx->makeCurrent(); - - foreach (QGLShader* shader, d->shaders) - glDetachShader(d->programId, shader->id()); - - d->shaders.clear(); - return true; -} - -#include - -bool QGLShaderProgram::link() -{ - Q_D(QGLShaderProgram); - - QGLContext* ctx = d->ctx; - if (!ctx) - return false; - ctx->makeCurrent(); - - glLinkProgram(d->programId); - - - GLint linked; - glGetProgramiv(d->programId, GL_LINK_STATUS, &linked); - - if (!linked) - return false; - - d->populateVariableLists(); - - d->valid = true; - return true; -} - -void QGLShaderProgram::use() -{ - Q_D(QGLShaderProgram); - if (!d->valid) - return; - - QGLContext *ctx = d->ctx; - glUseProgram(d->programId); -} - - -QString QGLShaderProgram::log() -{ - Q_D(QGLShaderProgram); - - QGLContext* ctx = d->ctx; - if (!ctx) - return QString(); - ctx->makeCurrent(); - - GLint logSize = -666; - glGetProgramiv(d->programId, GL_INFO_LOG_LENGTH, &logSize); - - char* logData = new char[logSize]; - GLint logLength; - - glGetProgramInfoLog(d->programId, logSize, &logLength, logData); - - QString result = QString::fromAscii(logData); - delete [] logData; - - return result; -} - -GLuint QGLShaderProgram::id() -{ - Q_D(QGLShaderProgram); - return d->programId; -} - -///////////////////////////////////////////////////////////////////////// - - - - -QGLUniform::QGLUniform() - : m_id(0), m_type(QGLInvalidType), ctx(0) -{ - qWarning("Unknown uniform! Either the uniform doesn't exist or it was removed at shader link"); -} - -const QGLUniform& QGLUniform::operator=(const GLfloat& rhs) const -{ - if (m_type != QGLFloatType) - return *this; - - glUniform1f(m_id, rhs); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const QGLVec2& rhs) const -{ - if (m_type != QGLVec2Type) - return *this; - - glUniform2fv(m_id, 1, (const GLfloat*)&rhs); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const QSizeF& rhs) const -{ - if (m_type != QGLVec2Type) - return *this; - - glUniform2f(m_id, rhs.width(), rhs.height()); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const QPointF& rhs) const -{ - if (m_type != QGLVec2Type) - return *this; - - glUniform2f(m_id, rhs.x(), rhs.y()); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const QGLVec3& rhs) const -{ - if (m_type != QGLVec3Type) - return *this; - - glUniform3fv(m_id, 1, (const GLfloat*)&rhs); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const QGLVec4& rhs) const -{ - if (m_type != QGLVec4Type) - return *this; - - glUniform4fv(m_id, 1, (const GLfloat*)&rhs); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const QColor& rhs) const -{ - if (m_type != QGLVec4Type) - return *this; - - glUniform4f(m_id, rhs.redF(), rhs.greenF(), rhs.blueF(), rhs.alphaF()); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const GLfloat rhs[2][2]) const -{ - if (m_type != QGLMat2Type) - return *this; - - glUniformMatrix2fv(m_id, 1, GL_FALSE, (GLfloat*)rhs); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const GLfloat rhs[3][3]) const -{ - if (m_type != QGLMat3Type) - return *this; - - glUniformMatrix3fv(m_id, 1, GL_FALSE, (GLfloat*)rhs); - - return *this; -} - -// Transposes ready for GL -const QGLUniform& QGLUniform::operator=(const QTransform& rhs) const -{ - if (m_type != QGLMat3Type) - return *this; - - GLfloat mat3[3][3] = { - {rhs.m11(), rhs.m12(), rhs.m13()}, - {rhs.m21(), rhs.m22(), rhs.m23()}, - {rhs.m31(), rhs.m32(), rhs.m33()} - }; - - glUniformMatrix3fv(m_id, 1, GL_FALSE, (GLfloat*)mat3); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const GLfloat rhs[4][4]) const -{ - if (m_type != QGLMat4Type) - return *this; - - glUniformMatrix4fv(m_id, 1, GL_FALSE, (GLfloat*)rhs); - - return *this; -} - -const QGLUniform& QGLUniform::operator=(const GLuint& rhs) const -{ - if ((m_type != QGLSampler2DType) || (m_type != QGLSamplerCubeType)) - return *this; - - glUniform1i(m_id, rhs); - - return *this; -} - - - - -///////////////////////////////////////////////////////////////////////// - -QGLVertexAttribute::QGLVertexAttribute() - : m_id(0), m_type(QGLInvalidType), ctx(0) -{ - qWarning("Unknown vertex attribute!"); -} - -void QGLVertexAttribute::enable() const -{ - glEnableVertexAttribArray(m_id); -} - -void QGLVertexAttribute::disable() const -{ - glDisableVertexAttribArray(m_id); -} - -// NOTE: Under PC emulation, QGLVec4Type is _always_ returned as the type, so this -// method isn't very useful. I.e. The datatypes are needed to distinguish the different -// sizes for the function signatures. -const QGLVertexAttribute& QGLVertexAttribute::operator=(const GLfloat* rhs) const -{ - int size = -1; - if (m_type == QGLFloatType) - size = 1; - else if (m_type == QGLVec2Type) - size = 2; - else if (m_type == QGLVec3Type) - size = 3; - else if (m_type == QGLVec4Type) - size = 4; - else if (m_type == QGLMat2Type) //### Not sure if this is right for matrix attributes... - size = 4; - else if (m_type == QGLMat3Type) //### Not sure if this is right for matrix attributes... - size = 9; - else if (m_type == QGLMat4Type) //### Not sure if this is right for matrix attributes... - size = 16; - else - return *this; - - glVertexAttribPointer(m_id, size, GL_FLOAT, GL_FALSE, 0, rhs); - - return *this; -} - -const QGLVertexAttribute& QGLVertexAttribute::operator=(const QGLVec3* rhs) const -{ - glVertexAttribPointer(m_id, 3, GL_FLOAT, GL_FALSE, 0, (GLfloat*)rhs); - - return *this; -} diff --git a/src/opengl/gl2paintengineex/qglshader_p.h b/src/opengl/gl2paintengineex/qglshader_p.h deleted file mode 100644 index 64c9a42..0000000 --- a/src/opengl/gl2paintengineex/qglshader_p.h +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -/* -Uniform Types in OpenGL ES 2.0 -============================== -GL_FLOAT GLfloat GLfloat -GL_FLOAT_VEC2 QGLVec2 GLfloat[2] -GL_FLOAT_VEC3 QGLVec3 GLfloat[3] -GL_FLOAT_VEC4 QGLVec4 GLfloat[4] -GL_INT GLint GLint -GL_INT_VEC2 QGLIVec2 GLint[2] -GL_INT_VEC3 QGLIVec3 GLint[3] -GL_INT_VEC4 QGLIVec4 GLint[4] -GL_BOOL GLbool GLbool -GL_BOOL_VEC2 QGLBVec2 GLbool[2] -GL_BOOL_VEC3 QGLBVec3 GLbool[3] -GL_BOOL_VEC4 QGLBVec4 GLbool[4] -GL_FLOAT_MAT2 QGLMat2 GLfloat[2][2] -GL_FLOAT_MAT3 QGLMat3 GLfloat[3][3] -GL_FLOAT_MAT4 QGLMat4 GLfloat[4][4] -GL_SAMPLER_2D QGLSampler2D GLuint -GL_SAMPLER_CUBE QGLSamplerCube GLuint - -Additional Types in Desktop OpenGL 2.0 -====================================== -SAMPLER_1D, -SAMPLER_3D, -SAMPLER_1D_SHADOW, -SAMPLER_2D_SHADOW. -*/ - -#include - -#define QGLShader QGLEngineShader -#define QGLShaderProgram QGLEngineShaderProgram - -typedef struct { - GLfloat a; - GLfloat b; -} QGLVec2; - -typedef struct { - GLfloat a; - GLfloat b; - GLfloat c; -} QGLVec3; - -typedef struct { - GLfloat a; - GLfloat b; - GLfloat c; - GLfloat d; -} QGLVec4; - - -class QGLShaderProgram; - -class QGLShaderPrivate; - -class QGLShader : QObject -{ - Q_OBJECT -public: - enum ShaderType {VertexShader, FragmentShader}; - - QGLShader(ShaderType type, const QGLContext* ctx = 0); - - GLuint id(); - void clearSource(); - void addSource(const QLatin1String& newSource); - bool compile(); - bool isValid(); - QString log(); - const QGLContext* context(); //maybe make private with prog a friend? - -private: - QGLShaderPrivate* d_ptr; - Q_DECLARE_PRIVATE(QGLShader); - -/* -public slots: - void cleanupGLContextRefs(const QGLContext *context); -*/ -}; - - -enum QGLType { - QGLInvalidType = 0, - QGLFloatType = GL_FLOAT, - QGLVec2Type = GL_FLOAT_VEC2, - QGLVec3Type = GL_FLOAT_VEC3, - QGLVec4Type = GL_FLOAT_VEC4, - QGLIntType = GL_INT, - QGLIVec2Type = GL_INT_VEC2, - QGLIVec3Type = GL_INT_VEC3, - QGLIVec4Type = GL_INT_VEC4, - QGLBoolType = GL_BOOL, - QGLBVec2Type = GL_BOOL_VEC2, - QGLBVec3Type = GL_BOOL_VEC3, - QGLBVec4Type = GL_BOOL_VEC4, - QGLMat2Type = GL_FLOAT_MAT2, - QGLMat3Type = GL_FLOAT_MAT3, - QGLMat4Type = GL_FLOAT_MAT4, - QGLSampler2DType = GL_SAMPLER_2D, - QGLSamplerCubeType = GL_SAMPLER_CUBE -}; - -class QGLUniform -{ -public: - - QGLUniform(GLenum glType, GLint location, QGLContext* context) - : m_id(location), m_type(QGLType(glType)), ctx(context) {} - - QGLUniform(); // Called by QMap when there's no match on the name - - QGLType type() const {return m_type;} - GLuint id() const {return m_id;} - - // Seems odd to be const, but it doesn't actually modify any of the - // class members, only the GL state! - const QGLUniform& operator=(const GLfloat&) const; - - const QGLUniform& operator=(const QGLVec2&) const; - const QGLUniform& operator=(const QSizeF&) const; - const QGLUniform& operator=(const QPointF&) const; - - const QGLUniform& operator=(const QGLVec3&) const; - - const QGLUniform& operator=(const QGLVec4&) const; - const QGLUniform& operator=(const QColor&) const; - - const QGLUniform& operator=(const GLfloat[2][2]) const; - - const QGLUniform& operator=(const GLfloat[3][3]) const; - const QGLUniform& operator=(const QTransform&) const; - - const QGLUniform& operator=(const GLfloat[4][4]) const; - - const QGLUniform& operator=(const GLuint&) const; // sampler2d, specifying a texture unit - - -protected: - GLuint m_id; - QGLType m_type; - QGLContext* ctx; -}; - -typedef QMap QGLUniformList; -typedef QMapIterator QGLUniformListIterator; - - -class QGLVertexAttribute -{ -public: - QGLVertexAttribute(GLenum glType, GLuint location, QGLContext* context) - : m_id(location), m_type(QGLType(glType)), ctx(context) {} - - QGLVertexAttribute(); // Called by QMap when there's no match on the name - - QGLType type() const {return m_type;} - GLuint id() const {return m_id;} - void enable() const; - void disable() const; - - const QGLVertexAttribute& operator=(const GLfloat* rhs) const; - const QGLVertexAttribute& operator=(const QGLVec3* rhs) const; - -protected: - GLuint m_id; - QGLType m_type; - QGLContext* ctx; -}; - -//TODO: Convert into setter overloads on QGLShaderProgram -typedef QMap QGLVertexAttributeList; -typedef QMapIterator QGLVertexAttributeListIterator; - - - -class QGLShaderProgramPrivate; - -class QGLShaderProgram : QObject -{ - Q_OBJECT -public: - QGLShaderProgram(const QGLContext* ctx = 0); - - const QGLUniformList & uniforms(); - const QGLVertexAttributeList& vertexAttributes(); - - bool addShader(QGLShader* newShader); - bool removeShader(QGLShader* oldShader); - bool removeAllShaders(); - - bool link(); - QString log(); - bool isValid(); - void use(); - - GLuint id(); - -private: - QGLShaderProgramPrivate* d_ptr; - Q_DECLARE_PRIVATE(QGLShaderProgram); - -/* -public slots: - void cleanupGLContextRefs(const QGLContext *context); -*/ -}; - -- cgit v0.12 From 861651c67a5f627f615ac1542f945e3c11593406 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 23 Apr 2009 09:16:53 +0200 Subject: Implement QRasterPaintEngine::clip(QRegion) to do something sensible... Since we now store QRegion's in the clipdata is possible for us to detect that we should go back to a rect-clip mode when we get to clip(region) or clip(rect) It turns out that the qt_span_fill_clipRegion is very slow, even for smaller regions, testcase was 3 rects, its 10% worse than span based clipping. For a fullscreen ellipse it was more in the range of 100x worse, so I removed the clip function entirely. --- src/gui/painting/qpaintengine_raster.cpp | 146 ++++++++++++++++++------------- src/gui/painting/qpaintengine_raster_p.h | 1 - 2 files changed, 86 insertions(+), 61 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 358dcea..c44763d 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -139,7 +139,6 @@ extern bool qt_cleartype_enabled; * Span functions */ static void qt_span_fill_clipRect(int count, const QSpan *spans, void *userData); -static void qt_span_fill_clipRegion(int count, const QSpan *spans, void *userData); static void qt_span_fill_clipped(int count, const QSpan *spans, void *userData); static void qt_span_clip(int count, const QSpan *spans, void *userData); static void qt_merge_clip(const QClipData *c1, const QClipData *c2, QClipData *result); @@ -1149,6 +1148,25 @@ void QRasterPaintEnginePrivate::updateMatrixData(QSpanData *spanData, const QBru } +static void qrasterpaintengine_state_setNoClip(QRasterPaintEngineState *s) +{ + if (s->flags.has_clip_ownership) + delete s->clip; + s->clip = 0; + s->flags.has_clip_ownership = false; +} + +static void qrasterpaintengine_dirty_clip(QRasterPaintEnginePrivate *d, QRasterPaintEngineState *s) +{ + s->fillFlags |= QPaintEngine::DirtyClipPath; + s->strokeFlags |= QPaintEngine::DirtyClipPath; + s->pixmapFlags |= QPaintEngine::DirtyClipPath; + + d->solid_color_filler.clip = d->clip(); + d->solid_color_filler.adjustSpanMethods(); +} + + /*! \internal */ @@ -1197,10 +1215,7 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) } if (op == Qt::NoClip) { - if (s->flags.has_clip_ownership) - delete s->clip; - s->clip = 0; - s->flags.has_clip_ownership = false; + qrasterpaintengine_state_setNoClip(s); } else { QClipData *base = d->baseClip; @@ -1242,13 +1257,7 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) s->clip = newClip; s->flags.has_clip_ownership = true; } - - s->fillFlags |= DirtyClipPath; - s->strokeFlags |= DirtyClipPath; - s->pixmapFlags |= DirtyClipPath; - - d->solid_color_filler.clip = d->clip(); - d->solid_color_filler.adjustSpanMethods(); + qrasterpaintengine_dirty_clip(d, s); } @@ -1266,10 +1275,7 @@ void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) QRasterPaintEngineState *s = state(); if (op == Qt::NoClip) { - if (s->flags.has_clip_ownership) - delete s->clip; - s->clip = d->baseClip; - s->flags.has_clip_ownership = false; + qrasterpaintengine_state_setNoClip(s); } else if (op == Qt::UniteClip || s->matrix.type() > QTransform::TxScale) { QPaintEngineEx::clip(rect, op); @@ -1313,32 +1319,63 @@ void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) return; } } - - s->brushData.clip = d->clip(); - s->penData.clip = d->clip(); - - s->fillFlags |= DirtyClipPath; - s->strokeFlags |= DirtyClipPath; - s->pixmapFlags |= DirtyClipPath; - - d->solid_color_filler.clip = d->clip(); - d->solid_color_filler.adjustSpanMethods(); + qrasterpaintengine_dirty_clip(d, s); } + /*! \internal */ void QRasterPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) { - QPaintEngineEx::clip(region, op); -} +#ifdef QT_DEBUG_DRAW + qDebug() << "QRasterPaintEngine::clip(): " << region << op; +#endif -/*! - \internal -*/ -void QRasterPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op) -{ - QPaintEngineEx::clip(path, op); + Q_D(QRasterPaintEngine); + + if (region.numRects() == 1) { + clip(region.boundingRect(), op); + return; + } + + QRasterPaintEngineState *s = state(); + const QClipData *clip = d->clip(); + const QClipData *baseClip = d->baseClip; + + if (op == Qt::NoClip) { + qrasterpaintengine_state_setNoClip(s); + } else if (s->matrix.type() > QTransform::TxScale + || op == Qt::UniteClip + || (op == Qt::IntersectClip && !clip->hasRectClip && !clip->hasRegionClip) + || (op == Qt::ReplaceClip && !baseClip->hasRectClip && !baseClip->hasRegionClip)) { + QPaintEngineEx::clip(region, op); + } else { + const QClipData *curClip; + QClipData *newClip; + + if (op == Qt::IntersectClip) + curClip = clip; + else + curClip = baseClip; + + if (s->flags.has_clip_ownership) { + newClip = s->clip; + Q_ASSERT(newClip); + } else { + newClip = new QClipData(d->rasterBuffer->height()); + s->clip = newClip; + s->flags.has_clip_ownership = true; + } + + QRegion r = s->matrix.map(region); + if (curClip->hasRectClip) + newClip->setClipRegion(r & curClip->clipRect); + else if (curClip->hasRegionClip) + newClip->setClipRegion(r & clip->clipRegion); + + qrasterpaintengine_dirty_clip(d, s); + } } /*! @@ -4387,6 +4424,7 @@ void QClipData::setClipRect(const QRect &rect) { // qDebug() << "setClipRect" << clipSpanHeight << count << allocated << rect; hasRectClip = true; + hasRegionClip = false; clipRect = rect; xmin = rect.x(); @@ -4394,6 +4432,12 @@ void QClipData::setClipRect(const QRect &rect) ymin = qMin(rect.y(), clipSpanHeight); ymax = qMin(rect.y() + rect.height(), clipSpanHeight); + if (m_spans) { + delete m_spans; + m_spans = 0; + } + + // qDebug() << xmin << xmax << ymin << ymax; } @@ -4408,6 +4452,7 @@ void QClipData::setClipRegion(const QRegion ®ion) } hasRegionClip = true; + hasRectClip = false; clipRegion = region; { // set bounding rect @@ -4417,6 +4462,12 @@ void QClipData::setClipRegion(const QRegion ®ion) ymin = rect.y(); ymax = rect.y() + rect.height(); } + + if (m_spans) { + delete m_spans; + m_spans = 0; + } + } /*! @@ -4661,29 +4712,6 @@ static void qt_span_fill_clipRect(int count, const QSpan *spans, fillData->unclipped_blend(count, spans, fillData); } -static void qt_span_fill_clipRegion(int count, const QSpan *spans, - void *userData) -{ - QSpanData *fillData = reinterpret_cast(userData); - Q_ASSERT(fillData->blend && fillData->unclipped_blend); - - Q_ASSERT(fillData->clip); - Q_ASSERT(!fillData->clip->clipRegion.isEmpty()); - - const int NSPANS = 256; - QSpan cspans[NSPANS]; - int currentClip = 0; - while (currentClip < count) { - const int unclipped = qt_intersect_spans(const_cast(spans), - count, ¤tClip, - &cspans[0], NSPANS, - fillData->clip->clipRegion); - if (unclipped > 0) - fillData->unclipped_blend(unclipped, cspans, fillData); - } - -} - static void qt_span_clip(int count, const QSpan *spans, void *userData) { ClipData *clipData = reinterpret_cast(userData); @@ -5108,8 +5136,6 @@ void QSpanData::adjustSpanMethods() blend = unclipped_blend; } else if (clip->hasRectClip) { blend = clip->clipRect.isEmpty() ? 0 : qt_span_fill_clipRect; - } else if (clip->hasRegionClip) { - blend = clip->clipRegion.isEmpty() ? 0 : qt_span_fill_clipRegion; } else { blend = qt_span_fill_clipped; } @@ -6086,7 +6112,7 @@ void dumpClip(int width, int height, QClipData *clip) int y1 = 0; for (int i = 0; i < clip->count; ++i) { - QSpan *span = clip->spans + i; + QSpan *span = clip->spans() + i; for (int j = 0; j < span->len; ++j) clipImg.setPixel(span->x + j, span->y, 0xffffff00); x0 = qMin(x0, int(span->x)); diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 26a2b3f..1f3f006 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -202,7 +202,6 @@ public: void clip(const QVectorPath &path, Qt::ClipOperation op); void clip(const QRect &rect, Qt::ClipOperation op); void clip(const QRegion ®ion, Qt::ClipOperation op); - void clip(const QPainterPath &path, Qt::ClipOperation op); enum ClipType { RectClip, -- cgit v0.12 From 9f1f048cb8c29f8c169afa0d5595acfa4eac606b Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 24 Apr 2009 09:29:06 +0200 Subject: Optimize intersected rect clipping in raster engine.. If we have span based clipping (complex) and we manage to intersect down to a plain rectangle, we switch back to rectangle mode which speeds up filling significantly... Reviewed-by: Samuel --- src/gui/painting/qpaintengine_raster.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index c44763d..bf84aa7 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4401,20 +4401,39 @@ void QClipData::fixup() ymax = m_spans[count-1].y + 1; xmin = INT_MAX; xmax = 0; + + bool isRect = true; + int left = m_spans[0].x; + int right = m_spans[0].x + m_spans[0].len; + for (int i = 0; i < count; ++i) { -// qDebug() << " " << spans[i].x << spans[i].y << spans[i].len << spans[i].coverage; if (m_spans[i].y != y) { + if (m_spans[i].y != y + 1 && y != -1) { + isRect = false; + } y = m_spans[i].y; m_clipLines[y].spans = m_spans+i; m_clipLines[y].count = 0; // qDebug() << " new line: y=" << y; } ++m_clipLines[y].count; + int sl = (int) m_spans[i].x; + int sr = sl + m_spans[i].len; + xmin = qMin(xmin, (int)m_spans[i].x); xmax = qMax(xmax, (int)m_spans[i].x + m_spans[i].len); + + if (sl != left || sr != right) + isRect = false; } ++xmax; -// qDebug("xmin=%d,xmax=%d,ymin=%d,ymax=%d", xmin, xmax, ymin, ymax); +// qDebug("xmin=%d,xmax=%d,ymin=%d,ymax=%d %s", xmin, xmax, ymin, ymax, isRect ? "rectangular" : ""); + + if (isRect) { + hasRectClip = true; + clipRect.setRect(xmin, ymin, xmax - xmin, ymax - ymin); + } + } /* -- cgit v0.12 From a90c924918f5705f900e2f55cfc5ca44ba3f8c3b Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 24 Apr 2009 10:45:01 +0200 Subject: Two buglets with clipping in raster engine In fillRect_normalized(), if we don't have user-clip we always have rectclip, so the initial value of the bool was false, and would cause the code to run through the slower code path. In unclipped_normalized(), the hasRegionClip must have been a typo left over from the falcon port. Reviewed-by: Samuel --- src/gui/painting/qpaintengine_raster.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index bf84aa7..20cea08 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1417,7 +1417,7 @@ static void fillRect_normalized(const QRect &r, QSpanData *data, { int x1, x2, y1, y2; - bool rectClipped = false; + bool rectClipped = true; if (data->clip) { x1 = qMax(r.x(), data->clip->xmin); @@ -3066,7 +3066,7 @@ bool QRasterPaintEnginePrivate::isUnclipped_normalized(const QRect &r) const if (cl->clipRect == deviceRect) return true; - if (cl->hasRegionClip) { + if (cl->hasRectClip) { // inline contains() for performance (we know the rects are normalized) const QRect &r1 = cl->clipRect; return (r.left() >= r1.left() && r.right() <= r1.right() -- cgit v0.12 From 8d93fb9149d20eb6110649c9fab2d0ef25960ccf Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 24 Apr 2009 10:48:10 +0200 Subject: compile... --- src/opengl/qglframebufferobject.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index b210285..b5d0088 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -160,8 +160,7 @@ QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjec Assigns \a other to this object. */ -QGLFramebufferObjectFormat::QGLFramebufferObjectFormat & -QGLFramebufferObjectFormat::operator=(const QGLFramebufferObjectFormat &other) +QGLFramebufferObjectFormat &QGLFramebufferObjectFormat::operator=(const QGLFramebufferObjectFormat &other) { *d = *other.d; return *this; -- cgit v0.12 From ae3c71bcc588f4b11158cb943c7dd453f066efc6 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 24 Apr 2009 13:37:25 +0200 Subject: Fix crash caused by clip(QRegion) in raster now depending on baseclip This was introduced by my recent implementation... --- src/gui/painting/qpaintengine_raster.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 20cea08..f950bad 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -362,7 +362,8 @@ void QRasterPaintEngine::init() d->basicStroker.setCubicToHook(qt_ft_outline_cubic_to); d->dashStroker = 0; - d->baseClip = 0; + d->baseClip = new QClipData(d->device->height()); + d->baseClip->setClipRect(QRect(0, 0, d->device->width(), d->device->height())); d->image_filler.init(d->rasterBuffer, this); d->image_filler.type = QSpanData::Texture; @@ -446,6 +447,8 @@ QRasterPaintEngine::~QRasterPaintEngine() delete d->outlineMapper; delete d->rasterizer; delete d->dashStroker; + + delete d->baseClip; } /*! @@ -541,11 +544,6 @@ bool QRasterPaintEngine::end() } #endif - if (d->baseClip) { - delete d->baseClip; - d->baseClip = 0; - } - return true; } @@ -1099,11 +1097,10 @@ void QRasterPaintEnginePrivate::systemStateChanged() if (!systemClip.isEmpty()) { QRegion clippedDeviceRgn = systemClip & clipRect; deviceRect = clippedDeviceRgn.boundingRect(); - delete baseClip; - baseClip = new QClipData(device->height()); baseClip->setClipRegion(clippedDeviceRgn); } else { deviceRect = clipRect; + baseClip->setClipRect(deviceRect); } #ifdef QT_DEBUG_DRAW qDebug() << "systemStateChanged" << this << "deviceRect" << deviceRect << clipRect << systemClip; -- cgit v0.12 From c429978d1a547e19c95db72f89755076b3b5bf1b Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 1 May 2009 11:22:10 +1000 Subject: Rename uses of QGLShaderProgram::errors() to log() Reviewed-by: trustme --- demos/boxes/scene.cpp | 6 +++--- src/opengl/gl2paintengineex/qglengineshadermanager.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/demos/boxes/scene.cpp b/demos/boxes/scene.cpp index e5aab75..cd9671e 100644 --- a/demos/boxes/scene.cpp +++ b/demos/boxes/scene.cpp @@ -620,11 +620,11 @@ void Scene::initGL() if (!program->link()) { qWarning("Failed to compile and link shader program"); qWarning("Vertex shader log:"); - qWarning() << m_vertexShader->errors(); + qWarning() << m_vertexShader->log(); qWarning() << "Fragment shader log ( file =" << file.absoluteFilePath() << "):"; - qWarning() << shader->errors(); + qWarning() << shader->log(); qWarning("Shader program log:"); - qWarning() << program->errors(); + qWarning() << program->log(); delete shader; delete program; diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 3d8d34b..d238830 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -156,7 +156,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) simpleShaderProg->link(); if (!simpleShaderProg->isValid()) { qCritical() << "Errors linking simple shader:" - << simpleShaderProg->errors(); + << simpleShaderProg->log(); } } @@ -432,7 +432,7 @@ bool QGLEngineShaderManager::useCorrectShaderProg() << " compositionFragShader = "<< requiredProgram.compositionFragShader->objectName() << '\n' #endif << " Error Log:" << '\n' - << " " << requiredProgram.program->errors(); + << " " << requiredProgram.program->log(); qWarning() << error; } else { -- cgit v0.12 From 8baf1a4dfb2b1a1bb7ecb5ada93ed9972f0e7762 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 5 May 2009 20:49:53 +0200 Subject: Fix OpenGL ES 2.0 breakages Enable GL graphics system on ES 2.0 builds - it wont work, but now QGLDrawable is being used it's just easier to build the graphics system. --- src/opengl/opengl.pro | 4 ++-- src/opengl/qgl.cpp | 2 ++ src/opengl/qwindowsurface_gl.cpp | 11 ++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 88af516..7cb8a71 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -15,10 +15,10 @@ contains(QT_CONFIG, opengl):CONFIG += opengl contains(QT_CONFIG, opengles1):CONFIG += opengles1 contains(QT_CONFIG, opengles2):CONFIG += opengles2 -!contains(QT_CONFIG, opengles2) { +#!contains(QT_CONFIG, opengles2) { HEADERS += qgraphicssystem_gl_p.h qwindowsurface_gl_p.h qpixmapdata_gl_p.h SOURCES += qgraphicssystem_gl.cpp qwindowsurface_gl.cpp qpixmapdata_gl.cpp -} +#} HEADERS += qgl.h \ qgl_p.h \ diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index d74ed95..907bc51 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1365,7 +1365,9 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32); int w = size.width(); int h = size.height(); +#if !defined(QT_OPENGL_ES_2) //### glGetTexImage not in GL ES 2.0, need to do something else here! glGetTexImage(qt_gl_preferredTextureTarget(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); +#endif convertFromGLImage(img, w, h, alpha_format, include_alpha); return img; } diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index d92241d..4c2748c 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -382,6 +382,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion; +#if !defined(QT_OPENGL_ES_2) if (!dirtyRegion.isEmpty()) { context()->makeCurrent(); @@ -407,6 +408,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & drawTexture(rect, d_ptr->tex_id, window()->size(), rect); } } +#endif d_ptr->paintedRegion = QRegion(); context()->swapBuffers(); @@ -455,7 +457,9 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & GL_NEAREST); glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); - } else { + } +#if !defined(QT_OPENGL_ES_2) + else { glDisable(GL_DEPTH_TEST); if (d_ptr->fbo) { @@ -485,6 +489,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & if (d_ptr->fbo) d_ptr->fbo->bind(); } +#endif if (ctx->format().doubleBuffer()) ctx->swapBuffers(); @@ -568,6 +573,7 @@ void QGLWindowSurface::updateGeometry() glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(target, 0); +#if !defined(QT_OPENGL_ES_2) glMatrixMode(GL_PROJECTION); glLoadIdentity(); #ifndef QT_OPENGL_ES @@ -575,6 +581,7 @@ void QGLWindowSurface::updateGeometry() #else glOrthof(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999); #endif +#endif // !defined(QT_OPENGL_ES_2) d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true; return; @@ -672,6 +679,7 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array); // qpaintengine_opengl.cpp qt_add_rect_to_array(rect, vertexArray); +#if !defined(QT_OPENGL_ES_2) glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray); glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray); @@ -683,6 +691,7 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#endif glDisable(target); glBindTexture(target, 0); -- cgit v0.12 From 7d6281973f8b0a5b53e63952f0d03624e6020454 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 5 May 2009 21:29:40 +0200 Subject: Big GL Extension Cleanup Clean up the extension naming and make things build on OpenGL ES 2.0 again. All the extensions which made it into OpenGL 2.0 spec have have the EXT postfix removed. This also eliminates defines on ES 2.0 as the code now refers to the in-spec names. Reviewed-by: sroedal --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 5 +- src/opengl/opengl.pro | 3 +- src/opengl/qgl.cpp | 10 +- src/opengl/qglextensions.cpp | 125 ++++++---- src/opengl/qglextensions_p.h | 272 +++++++++------------ src/opengl/qglframebufferobject.cpp | 76 +++--- src/opengl/qpixmapdata_gl.cpp | 10 +- src/opengl/qwindowsurface_gl.cpp | 4 +- 8 files changed, 253 insertions(+), 252 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 7dbdc32..1c0d7e0 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1059,8 +1059,9 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->height = sz.height(); d->mode = BrushDrawingMode; - qt_resolve_version_1_3_functions(d->ctx); - qt_resolve_glsl_extensions(d->ctx); +#if !defined(QT_OPENGL_ES_2) + qt_resolve_version_2_0_functions(d->ctx); +#endif d->last_engine = d->ctx->d_ptr->active_engine; d->ctx->d_ptr->active_engine = this; diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 7cb8a71..cfa9e4f 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -26,7 +26,8 @@ HEADERS += qgl.h \ qglpixelbuffer.h \ qglframebufferobject.h \ qglpixmapfilter_p.h \ - qglshaderprogram.h + qglshaderprogram.h \ + qglextensions_p.h SOURCES += qgl.cpp \ qglcolormap.cpp \ diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 907bc51..ccb6080 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1573,7 +1573,7 @@ void QGLContextPrivate::cleanup() Q_Q(QGLContext); if (pbo) { QGLContext *ctx = q; - glDeleteBuffersARB(1, &pbo); + glDeleteBuffers(1, &pbo); pbo = 0; } } @@ -1838,7 +1838,7 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint use_pbo = qt_resolve_buffer_extensions(ctx); if (use_pbo && pbo == 0) - glGenBuffersARB(1, &pbo); + glGenBuffers(1, &pbo); } // the GL_BGRA format is only present in GL version >= 1.2 @@ -1889,8 +1889,8 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint uchar *ptr = 0; if (use_pbo) { - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); - glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, img.width() * img.height() * 4, 0, GL_STREAM_DRAW_ARB); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); + glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, img.width() * img.height() * 4, 0, GL_STREAM_DRAW_ARB); ptr = reinterpret_cast(glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB)); } @@ -1917,7 +1917,7 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint } if (use_pbo) - glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); // this assumes the size of a texture is always smaller than the max cache size int cost = img.width()*img.height()*4/1024; diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp index 9ec76cb..3c198fb 100644 --- a/src/opengl/qglextensions.cpp +++ b/src/opengl/qglextensions.cpp @@ -45,9 +45,15 @@ QT_BEGIN_NAMESPACE bool qt_resolve_framebufferobject_extensions(QGLContext *ctx) { -#if !defined(QT_OPENGL_ES_2) - if (glIsRenderbufferEXT != 0) +#if defined(QT_OPENGL_ES_2) + static bool have_resolved = false; + if (have_resolved) return true; + have_resolved = true; +#else + if (glIsRenderbuffer != 0) + return true; +#endif if (ctx == 0) { qWarning("QGLFramebufferObject: Unable to resolve framebuffer object extensions -" @@ -55,35 +61,37 @@ bool qt_resolve_framebufferobject_extensions(QGLContext *ctx) return false; } - glIsRenderbufferEXT = (_glIsRenderbufferEXT) ctx->getProcAddress(QLatin1String("glIsRenderbufferEXT")); - glBindRenderbufferEXT = (_glBindRenderbufferEXT) ctx->getProcAddress(QLatin1String("glBindRenderbufferEXT")); - glDeleteRenderbuffersEXT = (_glDeleteRenderbuffersEXT) ctx->getProcAddress(QLatin1String("glDeleteRenderbuffersEXT")); - glGenRenderbuffersEXT = (_glGenRenderbuffersEXT) ctx->getProcAddress(QLatin1String("glGenRenderbuffersEXT")); - glRenderbufferStorageEXT = (_glRenderbufferStorageEXT) ctx->getProcAddress(QLatin1String("glRenderbufferStorageEXT")); - glGetRenderbufferParameterivEXT = - (_glGetRenderbufferParameterivEXT) ctx->getProcAddress(QLatin1String("glGetRenderbufferParameterivEXT")); - glIsFramebufferEXT = (_glIsFramebufferEXT) ctx->getProcAddress(QLatin1String("glIsFramebufferEXT")); - glBindFramebufferEXT = (_glBindFramebufferEXT) ctx->getProcAddress(QLatin1String("glBindFramebufferEXT")); - glDeleteFramebuffersEXT = (_glDeleteFramebuffersEXT) ctx->getProcAddress(QLatin1String("glDeleteFramebuffersEXT")); - glGenFramebuffersEXT = (_glGenFramebuffersEXT) ctx->getProcAddress(QLatin1String("glGenFramebuffersEXT")); - glCheckFramebufferStatusEXT = (_glCheckFramebufferStatusEXT) ctx->getProcAddress(QLatin1String("glCheckFramebufferStatusEXT")); - glFramebufferTexture1DEXT = (_glFramebufferTexture1DEXT) ctx->getProcAddress(QLatin1String("glFramebufferTexture1DEXT")); - glFramebufferTexture2DEXT = (_glFramebufferTexture2DEXT) ctx->getProcAddress(QLatin1String("glFramebufferTexture2DEXT")); - glFramebufferTexture3DEXT = (_glFramebufferTexture3DEXT) ctx->getProcAddress(QLatin1String("glFramebufferTexture3DEXT")); - glFramebufferRenderbufferEXT = (_glFramebufferRenderbufferEXT) ctx->getProcAddress(QLatin1String("glFramebufferRenderbufferEXT")); - glGetFramebufferAttachmentParameterivEXT = - (_glGetFramebufferAttachmentParameterivEXT) ctx->getProcAddress(QLatin1String("glGetFramebufferAttachmentParameterivEXT")); - glGenerateMipmapEXT = (_glGenerateMipmapEXT) ctx->getProcAddress(QLatin1String("glGenerateMipmapEXT")); + glBlitFramebufferEXT = (_glBlitFramebufferEXT) ctx->getProcAddress(QLatin1String("glBlitFramebufferEXT")); glRenderbufferStorageMultisampleEXT = (_glRenderbufferStorageMultisampleEXT) ctx->getProcAddress(QLatin1String("glRenderbufferStorageMultisampleEXT")); - return glIsRenderbufferEXT; + +#if !defined(QT_OPENGL_ES_2) + glIsRenderbuffer = (_glIsRenderbuffer) ctx->getProcAddress(QLatin1String("glIsRenderbufferEXT")); + glBindRenderbuffer = (_glBindRenderbuffer) ctx->getProcAddress(QLatin1String("glBindRenderbufferEXT")); + glDeleteRenderbuffers = (_glDeleteRenderbuffers) ctx->getProcAddress(QLatin1String("glDeleteRenderbuffersEXT")); + glGenRenderbuffers = (_glGenRenderbuffers) ctx->getProcAddress(QLatin1String("glGenRenderbuffersEXT")); + glRenderbufferStorage = (_glRenderbufferStorage) ctx->getProcAddress(QLatin1String("glRenderbufferStorageEXT")); + glGetRenderbufferParameteriv = + (_glGetRenderbufferParameteriv) ctx->getProcAddress(QLatin1String("glGetRenderbufferParameterivEXT")); + glIsFramebuffer = (_glIsFramebuffer) ctx->getProcAddress(QLatin1String("glIsFramebufferEXT")); + glBindFramebuffer = (_glBindFramebuffer) ctx->getProcAddress(QLatin1String("glBindFramebufferEXT")); + glDeleteFramebuffers = (_glDeleteFramebuffers) ctx->getProcAddress(QLatin1String("glDeleteFramebuffersEXT")); + glGenFramebuffers = (_glGenFramebuffers) ctx->getProcAddress(QLatin1String("glGenFramebuffersEXT")); + glCheckFramebufferStatus = (_glCheckFramebufferStatus) ctx->getProcAddress(QLatin1String("glCheckFramebufferStatusEXT")); + glFramebufferTexture2D = (_glFramebufferTexture2D) ctx->getProcAddress(QLatin1String("glFramebufferTexture2DEXT")); + glFramebufferRenderbuffer = (_glFramebufferRenderbuffer) ctx->getProcAddress(QLatin1String("glFramebufferRenderbufferEXT")); + glGetFramebufferAttachmentParameteriv = + (_glGetFramebufferAttachmentParameteriv) ctx->getProcAddress(QLatin1String("glGetFramebufferAttachmentParameterivEXT")); + glGenerateMipmap = (_glGenerateMipmap) ctx->getProcAddress(QLatin1String("glGenerateMipmapEXT")); + + return glIsRenderbuffer; #else - Q_UNUSED(ctx); return true; #endif } +#if !defined(QT_OPENGL_ES_2) bool qt_resolve_version_1_3_functions(QGLContext *ctx) { if (glMultiTexCoord4f != 0) @@ -92,14 +100,12 @@ bool qt_resolve_version_1_3_functions(QGLContext *ctx) QGLContext cx(QGLFormat::defaultFormat()); glMultiTexCoord4f = (_glMultiTexCoord4f) ctx->getProcAddress(QLatin1String("glMultiTexCoord4f")); -#if defined(QT_OPENGL_ES_2) - return glMultiTexCoord4f; -#else glActiveTexture = (_glActiveTexture) ctx->getProcAddress(QLatin1String("glActiveTexture")); return glMultiTexCoord4f && glActiveTexture; -#endif } +#endif +#if !defined(QT_OPENGL_ES_2) bool qt_resolve_stencil_face_extension(QGLContext *ctx) { if (glActiveStencilFaceEXT != 0) @@ -110,7 +116,10 @@ bool qt_resolve_stencil_face_extension(QGLContext *ctx) return glActiveStencilFaceEXT; } +#endif + +#if !defined(QT_OPENGL_ES_2) bool qt_resolve_frag_program_extensions(QGLContext *ctx) { if (glProgramStringARB != 0) @@ -129,26 +138,36 @@ bool qt_resolve_frag_program_extensions(QGLContext *ctx) && glGenProgramsARB && glProgramLocalParameter4fvARB; } +#endif + bool qt_resolve_buffer_extensions(QGLContext *ctx) { - if (glBindBufferARB && glDeleteBuffersARB && glGenBuffersARB && glBufferDataARB - && glMapBufferARB && glUnmapBufferARB) + if (glMapBufferARB && glUnmapBufferARB +#if !defined(QT_OPENGL_ES_2) + && glBindBuffer && glDeleteBuffers && glGenBuffers && glBufferData +#endif + ) return true; - glBindBufferARB = (_glBindBufferARB) ctx->getProcAddress(QLatin1String("glBindBufferARB")); - glDeleteBuffersARB = (_glDeleteBuffersARB) ctx->getProcAddress(QLatin1String("glDeleteBuffersARB")); - glGenBuffersARB = (_glGenBuffersARB) ctx->getProcAddress(QLatin1String("glGenBuffersARB")); - glBufferDataARB = (_glBufferDataARB) ctx->getProcAddress(QLatin1String("glBufferDataARB")); +#if !defined(QT_OPENGL_ES_2) + glBindBuffer = (_glBindBuffer) ctx->getProcAddress(QLatin1String("glBindBufferARB")); + glDeleteBuffers = (_glDeleteBuffers) ctx->getProcAddress(QLatin1String("glDeleteBuffersARB")); + glGenBuffers = (_glGenBuffers) ctx->getProcAddress(QLatin1String("glGenBuffersARB")); + glBufferData = (_glBufferData) ctx->getProcAddress(QLatin1String("glBufferDataARB")); +#endif glMapBufferARB = (_glMapBufferARB) ctx->getProcAddress(QLatin1String("glMapBufferARB")); glUnmapBufferARB = (_glUnmapBufferARB) ctx->getProcAddress(QLatin1String("glUnmapBufferARB")); - return glBindBufferARB - && glDeleteBuffersARB - && glGenBuffersARB - && glBufferDataARB - && glMapBufferARB - && glUnmapBufferARB; + return glMapBufferARB + && glUnmapBufferARB +#if !defined(QT_OPENGL_ES_2) + && glBindBuffer + && glDeleteBuffers + && glGenBuffers + && glBufferData +#endif + ; } bool qt_resolve_glsl_extensions(QGLContext *ctx) @@ -215,7 +234,6 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glDisableVertexAttribArray = (_glDisableVertexAttribArray) ctx->getProcAddress(QLatin1String("glDisableVertexAttribArray")); glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArray")); - glStencilOpSeparate = (_glStencilOpSeparate) ctx->getProcAddress(QLatin1String("glStencilOpSeparate")); //### Not really a glsl extension, but needed for gl2 } else { // We may not have the standard shader functions, but we might // have the older ARB functions instead. @@ -266,8 +284,6 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glVertexAttribPointer = (_glVertexAttribPointer) ctx->getProcAddress(QLatin1String("glVertexAttribPointerARB")); glDisableVertexAttribArray = (_glDisableVertexAttribArray) ctx->getProcAddress(QLatin1String("glDisableVertexAttribArrayARB")); glEnableVertexAttribArray = (_glEnableVertexAttribArray) ctx->getProcAddress(QLatin1String("glEnableVertexAttribArrayARB")); - - glStencilOpSeparate = 0; //### Was never an ARB extension but went strait into OpenGL 2.0 } // Note: glShaderBinary(), glIsShader(), glIsProgram(), and @@ -307,9 +323,30 @@ bool qt_resolve_glsl_extensions(QGLContext *ctx) glVertexAttrib4fv && glVertexAttribPointer && glDisableVertexAttribArray && - glEnableVertexAttribArray && - glStencilOpSeparate; + glEnableVertexAttribArray; #endif } +#if !defined(QT_OPENGL_ES_2) +bool qt_resolve_version_2_0_functions(QGLContext *ctx) +{ + bool gl2supported = true; + if (!qt_resolve_glsl_extensions(ctx)) + gl2supported = false; + + if (!qt_resolve_version_1_3_functions(ctx)) + gl2supported = false; + + if (glStencilOpSeparate) + return gl2supported; + + glStencilOpSeparate = (_glStencilOpSeparate) ctx->getProcAddress(QLatin1String("glStencilOpSeparate")); + if (!glStencilOpSeparate) + gl2supported = false; + + return gl2supported; +} +#endif + + QT_END_NAMESPACE diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 793400a..46047ef 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -79,10 +79,10 @@ typedef char GLchar; #endif // ARB_pixel_buffer_object -typedef void (APIENTRY *_glBindBufferARB) (GLenum, GLuint); -typedef void (APIENTRY *_glDeleteBuffersARB) (GLsizei, const GLuint *); -typedef void (APIENTRY *_glGenBuffersARB) (GLsizei, GLuint *); -typedef void (APIENTRY *_glBufferDataARB) (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); +typedef void (APIENTRY *_glBindBuffer) (GLenum, GLuint); +typedef void (APIENTRY *_glDeleteBuffers) (GLsizei, const GLuint *); +typedef void (APIENTRY *_glGenBuffers) (GLsizei, GLuint *); +typedef void (APIENTRY *_glBufferData) (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); typedef GLvoid* (APIENTRY *_glMapBufferARB) (GLenum, GLenum); typedef GLboolean (APIENTRY *_glUnmapBufferARB) (GLenum); @@ -145,50 +145,34 @@ typedef void (APIENTRY *_glEnableVertexAttribArray) (GLuint); typedef void (APIENTRY *_glGetProgramBinaryOES) (GLuint, GLsizei, GLsizei *, GLenum *, void *); typedef void (APIENTRY *_glProgramBinaryOES) (GLuint, GLenum, const void *, GLint); -typedef void (APIENTRY *_glActiveStencilFaceEXT) (GLenum ); typedef void (APIENTRY *_glMultiTexCoord4f) (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *_glActiveTexture) (GLenum); +typedef void (APIENTRY *_glActiveStencilFaceEXT) (GLenum ); -typedef void (APIENTRY *_glGetActiveAttrib) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -typedef GLint (APIENTRY *_glGetAttribLocation) (GLuint program, const GLchar* name); -typedef void (APIENTRY *_glGetActiveUniform) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -typedef void (APIENTRY *_glGetProgramInfoLog) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); -typedef void (APIENTRY *_glUniform1f) (GLint location, GLfloat v0); -typedef void (APIENTRY *_glUniform2f) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRY *_glUniform4f) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRY *_glUniformMatrix2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (APIENTRY *_glUniformMatrix3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (APIENTRY *_glUniformMatrix4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -typedef void (APIENTRY *_glEnableVertexAttribArray) (GLuint); -typedef void (APIENTRY *_glDisableVertexAttribArray) (GLuint); -typedef void (APIENTRY *_glVertexAttribPointer) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); +// Needed for GL2 engine: typedef void (APIENTRY *_glStencilOpSeparate) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRY *_glActiveTexture) (GLenum); // EXT_GL_framebuffer_object -typedef GLboolean (APIENTRY *_glIsRenderbufferEXT) (GLuint renderbuffer); -typedef void (APIENTRY *_glBindRenderbufferEXT) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRY *_glDeleteRenderbuffersEXT) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRY *_glGenRenderbuffersEXT) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRY *_glRenderbufferStorageEXT) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRY *_glGetRenderbufferParameterivEXT) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRY *_glIsFramebufferEXT) (GLuint framebuffer); -typedef void (APIENTRY *_glBindFramebufferEXT) (GLenum target, GLuint framebuffer); -typedef void (APIENTRY *_glDeleteFramebuffersEXT) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRY *_glGenFramebuffersEXT) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRY *_glCheckFramebufferStatusEXT) (GLenum target); -typedef void (APIENTRY *_glFramebufferTexture1DEXT) (GLenum target, GLenum attachment, GLenum textarget, +typedef GLboolean (APIENTRY *_glIsRenderbuffer) (GLuint renderbuffer); +typedef void (APIENTRY *_glBindRenderbuffer) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRY *_glDeleteRenderbuffers) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRY *_glGenRenderbuffers) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRY *_glRenderbufferStorage) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRY *_glGetRenderbufferParameteriv) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRY *_glIsFramebuffer) (GLuint framebuffer); +typedef void (APIENTRY *_glBindFramebuffer) (GLenum target, GLuint framebuffer); +typedef void (APIENTRY *_glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRY *_glGenFramebuffers) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRY *_glCheckFramebufferStatus) (GLenum target); +typedef void (APIENTRY *_glFramebufferTexture2D) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRY *_glFramebufferTexture2DEXT) (GLenum target, GLenum attachment, GLenum textarget, - GLuint texture, GLint level); -typedef void (APIENTRY *_glFramebufferTexture3DEXT) (GLenum target, GLenum attachment, GLenum textarget, - GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRY *_glFramebufferRenderbufferEXT) (GLenum target, GLenum attachment, GLenum renderbuffertarget, +typedef void (APIENTRY *_glFramebufferRenderbuffer) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRY *_glGetFramebufferAttachmentParameterivEXT) (GLenum target, GLenum attachment, GLenum pname, +typedef void (APIENTRY *_glGetFramebufferAttachmentParameteriv) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRY *_glGenerateMipmapEXT) (GLenum target); +typedef void (APIENTRY *_glGenerateMipmap) (GLenum target); // EXT_GL_framebuffer_blit typedef void (APIENTRY *_glBlitFramebufferEXT) (int srcX0, int srcY0, int srcX1, int srcY1, @@ -204,13 +188,14 @@ QT_BEGIN_NAMESPACE struct QGLExtensionFuncs { QGLExtensionFuncs() { +#if !defined(QT_OPENGL_ES_2) qt_glProgramStringARB = 0; qt_glBindProgramARB = 0; qt_glDeleteProgramsARB = 0; qt_glGenProgramsARB = 0; qt_glProgramLocalParameter4fvARB = 0; -#if !defined(QT_OPENGL_ES_2) + // GLSL qt_glCreateShader = 0; qt_glShaderSource = 0; qt_glShaderBinary = 0; @@ -258,6 +243,13 @@ struct QGLExtensionFuncs qt_glVertexAttribPointer = 0; qt_glDisableVertexAttribArray = 0; qt_glEnableVertexAttribArray = 0; + + // Extras for GL2 engine: + qt_glActiveTexture = 0; + qt_glStencilOpSeparate = 0; + + qt_glActiveStencilFaceEXT = 0; + qt_glMultiTexCoord4f = 0; #else qt_glslResolved = false; @@ -265,63 +257,46 @@ struct QGLExtensionFuncs qt_glProgramBinaryOES = 0; #endif - qt_glActiveStencilFaceEXT = 0; - - qt_glMultiTexCoord4f = 0; - qt_glActiveTexture = 0; - + // FBOs #if !defined(QT_OPENGL_ES_2) - qt_glIsRenderbufferEXT = 0; - qt_glBindRenderbufferEXT = 0; - qt_glDeleteRenderbuffersEXT = 0; - qt_glGenRenderbuffersEXT = 0; - qt_glRenderbufferStorageEXT = 0; - qt_glGetRenderbufferParameterivEXT = 0; - qt_glIsFramebufferEXT = 0; - qt_glBindFramebufferEXT = 0; - qt_glDeleteFramebuffersEXT = 0; - qt_glGenFramebuffersEXT = 0; - qt_glCheckFramebufferStatusEXT = 0; - qt_glFramebufferTexture1DEXT = 0; - qt_glFramebufferTexture2DEXT = 0; - qt_glFramebufferTexture3DEXT = 0; - qt_glFramebufferRenderbufferEXT = 0; - qt_glGetFramebufferAttachmentParameterivEXT = 0; - qt_glGenerateMipmapEXT = 0; + qt_glIsRenderbuffer = 0; + qt_glBindRenderbuffer = 0; + qt_glDeleteRenderbuffers = 0; + qt_glGenRenderbuffers = 0; + qt_glRenderbufferStorage = 0; + qt_glGetRenderbufferParameteriv = 0; + qt_glIsFramebuffer = 0; + qt_glBindFramebuffer = 0; + qt_glDeleteFramebuffers = 0; + qt_glGenFramebuffers = 0; + qt_glCheckFramebufferStatus = 0; + qt_glFramebufferTexture2D = 0; + qt_glFramebufferRenderbuffer = 0; + qt_glGetFramebufferAttachmentParameteriv = 0; + qt_glGenerateMipmap = 0; #endif qt_glBlitFramebufferEXT = 0; qt_glRenderbufferStorageMultisampleEXT = 0; - qt_glBindBufferARB = 0; - qt_glDeleteBuffersARB = 0; - qt_glGenBuffersARB = 0; - qt_glBufferDataARB = 0; + // Buffer objects: +#if !defined(QT_OPENGL_ES_2) + qt_glBindBuffer = 0; + qt_glDeleteBuffers = 0; + qt_glGenBuffers = 0; + qt_glBufferData = 0; +#endif qt_glMapBufferARB = 0; qt_glUnmapBufferARB = 0; - - qt_glGetActiveAttrib = 0; - qt_glGetAttribLocation = 0; - qt_glGetActiveUniform = 0; - qt_glGetProgramInfoLog = 0; - qt_glUniform1f = 0; - qt_glUniform2f = 0; - qt_glUniform4f = 0; - qt_glUniformMatrix2fv = 0; - qt_glUniformMatrix3fv = 0; - qt_glUniformMatrix4fv = 0; - qt_glEnableVertexAttribArray = 0; - qt_glDisableVertexAttribArray = 0; - qt_glVertexAttribPointer = 0; - qt_glStencilOpSeparate = 0; } + +#if !defined(QT_OPENGL_ES_2) _glProgramStringARB qt_glProgramStringARB; _glBindProgramARB qt_glBindProgramARB; _glDeleteProgramsARB qt_glDeleteProgramsARB; _glGenProgramsARB qt_glGenProgramsARB; _glProgramLocalParameter4fvARB qt_glProgramLocalParameter4fvARB; -#if !defined(QT_OPENGL_ES_2) // GLSL definitions _glCreateShader qt_glCreateShader; _glShaderSource qt_glShaderSource; @@ -370,6 +345,7 @@ struct QGLExtensionFuncs _glVertexAttribPointer qt_glVertexAttribPointer; _glDisableVertexAttribArray qt_glDisableVertexAttribArray; _glEnableVertexAttribArray qt_glEnableVertexAttribArray; + #else bool qt_glslResolved; @@ -378,45 +354,45 @@ struct QGLExtensionFuncs #endif _glActiveStencilFaceEXT qt_glActiveStencilFaceEXT; - _glMultiTexCoord4f qt_glMultiTexCoord4f; + +#if !defined(QT_OPENGL_ES_2) + // Extras needed for GL2 engine: _glActiveTexture qt_glActiveTexture; + _glStencilOpSeparate qt_glStencilOpSeparate; +#endif + // FBOs #if !defined(QT_OPENGL_ES_2) - _glIsRenderbufferEXT qt_glIsRenderbufferEXT; - _glBindRenderbufferEXT qt_glBindRenderbufferEXT; - _glDeleteRenderbuffersEXT qt_glDeleteRenderbuffersEXT; - _glGenRenderbuffersEXT qt_glGenRenderbuffersEXT; - _glRenderbufferStorageEXT qt_glRenderbufferStorageEXT; - _glGetRenderbufferParameterivEXT qt_glGetRenderbufferParameterivEXT; - _glIsFramebufferEXT qt_glIsFramebufferEXT; - _glBindFramebufferEXT qt_glBindFramebufferEXT; - _glDeleteFramebuffersEXT qt_glDeleteFramebuffersEXT; - _glGenFramebuffersEXT qt_glGenFramebuffersEXT; - _glCheckFramebufferStatusEXT qt_glCheckFramebufferStatusEXT; - _glFramebufferTexture1DEXT qt_glFramebufferTexture1DEXT; - _glFramebufferTexture2DEXT qt_glFramebufferTexture2DEXT; - _glFramebufferTexture3DEXT qt_glFramebufferTexture3DEXT; - _glFramebufferRenderbufferEXT qt_glFramebufferRenderbufferEXT; - _glGetFramebufferAttachmentParameterivEXT qt_glGetFramebufferAttachmentParameterivEXT; - _glGenerateMipmapEXT qt_glGenerateMipmapEXT; + _glIsRenderbuffer qt_glIsRenderbuffer; + _glBindRenderbuffer qt_glBindRenderbuffer; + _glDeleteRenderbuffers qt_glDeleteRenderbuffers; + _glGenRenderbuffers qt_glGenRenderbuffers; + _glRenderbufferStorage qt_glRenderbufferStorage; + _glGetRenderbufferParameteriv qt_glGetRenderbufferParameteriv; + _glIsFramebuffer qt_glIsFramebuffer; + _glBindFramebuffer qt_glBindFramebuffer; + _glDeleteFramebuffers qt_glDeleteFramebuffers; + _glGenFramebuffers qt_glGenFramebuffers; + _glCheckFramebufferStatus qt_glCheckFramebufferStatus; + _glFramebufferTexture2D qt_glFramebufferTexture2D; + _glFramebufferRenderbuffer qt_glFramebufferRenderbuffer; + _glGetFramebufferAttachmentParameteriv qt_glGetFramebufferAttachmentParameteriv; + _glGenerateMipmap qt_glGenerateMipmap; #endif _glBlitFramebufferEXT qt_glBlitFramebufferEXT; _glRenderbufferStorageMultisampleEXT qt_glRenderbufferStorageMultisampleEXT; - _glBindBufferARB qt_glBindBufferARB; - _glDeleteBuffersARB qt_glDeleteBuffersARB; - _glGenBuffersARB qt_glGenBuffersARB; - _glBufferDataARB qt_glBufferDataARB; + // Buffer objects +#if !defined(QT_OPENGL_ES_2) + _glBindBuffer qt_glBindBuffer; + _glDeleteBuffers qt_glDeleteBuffers; + _glGenBuffers qt_glGenBuffers; + _glBufferData qt_glBufferData; +#endif _glMapBufferARB qt_glMapBufferARB; _glUnmapBufferARB qt_glUnmapBufferARB; - _glGetActiveAttrib qt_glGetActiveAttrib; - _glGetActiveUniform qt_glGetActiveUniform; - _glUniform1f qt_glUniform1f; - _glUniform2f qt_glUniform2f; - _glUniform4f qt_glUniform4f; - _glStencilOpSeparate qt_glStencilOpSeparate; }; @@ -619,6 +595,8 @@ struct QGLExtensionFuncs #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A #endif + +#if !defined(QT_OPENGL_ES_2) #define glProgramStringARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glProgramStringARB #define glBindProgramARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindProgramARB #define glDeleteProgramsARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteProgramsARB @@ -629,61 +607,44 @@ struct QGLExtensionFuncs #define glMultiTexCoord4f QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glMultiTexCoord4f -#if !defined(QT_OPENGL_ES_2) #define glActiveTexture QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glActiveTexture -#endif +#endif // !defined(QT_OPENGL_ES_2) -#if !defined(QT_OPENGL_ES_2) -#define glIsRenderbufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glIsRenderbufferEXT -#define glBindRenderbufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindRenderbufferEXT -#define glDeleteRenderbuffersEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteRenderbuffersEXT -#define glGenRenderbuffersEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenRenderbuffersEXT -#define glRenderbufferStorageEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glRenderbufferStorageEXT -#define glGetRenderbufferParameterivEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetRenderbufferParameterivEXT -#define glIsFramebufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glIsFramebufferEXT -#define glBindFramebufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindFramebufferEXT -#define glDeleteFramebuffersEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteFramebuffersEXT -#define glGenFramebuffersEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenFramebuffersEXT -#define glCheckFramebufferStatusEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glCheckFramebufferStatusEXT -#define glFramebufferTexture1DEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glFramebufferTexture1DEXT -#define glFramebufferTexture2DEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glFramebufferTexture2DEXT -#define glFramebufferTexture3DEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glFramebufferTexture3DEXT -#define glFramebufferRenderbufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glFramebufferRenderbufferEXT -#define glGetFramebufferAttachmentParameterivEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetFramebufferAttachmentParameterivEXT -#define glGenerateMipmapEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenerateMipmapEXT +// FBOs +#if !defined(QT_OPENGL_ES_2) +#define glIsRenderbuffer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glIsRenderbuffer +#define glBindRenderbuffer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindRenderbuffer +#define glDeleteRenderbuffers QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteRenderbuffers +#define glGenRenderbuffers QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenRenderbuffers +#define glRenderbufferStorage QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glRenderbufferStorage +#define glGetRenderbufferParameteriv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetRenderbufferParameteriv +#define glIsFramebuffer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glIsFramebuffer +#define glBindFramebuffer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindFramebuffer +#define glDeleteFramebuffers QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteFramebuffers +#define glGenFramebuffers QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenFramebuffers +#define glCheckFramebufferStatus QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glCheckFramebufferStatus +#define glFramebufferTexture2D QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glFramebufferTexture2D +#define glFramebufferRenderbuffer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glFramebufferRenderbuffer +#define glGetFramebufferAttachmentParameteriv QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGetFramebufferAttachmentParameteriv +#define glGenerateMipmap QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenerateMipmap +#endif // QT_OPENGL_ES_2 #define glBlitFramebufferEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBlitFramebufferEXT #define glRenderbufferStorageMultisampleEXT QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glRenderbufferStorageMultisampleEXT -#else // QT_OPENGL_ES_2 - -#define glIsRenderbufferEXT glIsRenderbuffer -#define glBindRenderbufferEXT glBindRenderbuffer -#define glDeleteRenderbuffersEXT glDeleteRenderbuffers -#define glGenRenderbuffersEXT glGenRenderbuffers -#define glRenderbufferStorageEXT glRenderbufferStorage -#define glGetRenderbufferParameterivEXT glGetRenderbufferParameteriv -#define glIsFramebufferEXT glIsFramebuffer -#define glBindFramebufferEXT glBindFramebuffer -#define glDeleteFramebuffersEXT glDeleteFramebuffers -#define glGenFramebuffersEXT glGenFramebuffers -#define glCheckFramebufferStatusEXT glCheckFramebufferStatus -#define glFramebufferTexture1DEXT glFramebufferTexture1D -#define glFramebufferTexture2DEXT glFramebufferTexture2D -#define glFramebufferTexture3DEXT glFramebufferTexture3D -#define glFramebufferRenderbufferEXT glFramebufferRenderbuffer -#define glGetFramebufferAttachmentParameterivEXT glGetFramebufferAttachmentParameteriv -#define glGenerateMipmapEXT glGenerateMipmap -#endif // QT_OPENGL_ES_2 - -#define glBindBufferARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindBufferARB -#define glDeleteBuffersARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteBuffersARB -#define glGenBuffersARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenBuffersARB -#define glBufferDataARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBufferDataARB +// Buffer objects +#if !defined(QT_OPENGL_ES_2) +#define glBindBuffer QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBindBuffer +#define glDeleteBuffers QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glDeleteBuffers +#define glGenBuffers QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glGenBuffers +#define glBufferData QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glBufferData +#endif #define glMapBufferARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glMapBufferARB #define glUnmapBufferARB QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glUnmapBufferARB + +// GLSL #if !defined(QT_OPENGL_ES_2) #define glCreateShader QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glCreateShader @@ -741,9 +702,9 @@ struct QGLExtensionFuncs #endif // QT_OPENGL_ES_2 -#define glStencilOpSeparate QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glStencilOpSeparate #if !defined(QT_OPENGL_ES_2) +#define glStencilOpSeparate QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glStencilOpSeparate #define glClearDepthf(x) glClearDepth(GLdouble(x)) #endif @@ -751,6 +712,7 @@ extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx); bool qt_resolve_buffer_extensions(QGLContext *ctx); bool qt_resolve_version_1_3_functions(QGLContext *ctx); +bool qt_resolve_version_2_0_functions(QGLContext *ctx); bool qt_resolve_stencil_face_extension(QGLContext *ctx); bool qt_resolve_frag_program_extensions(QGLContext *ctx); diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index b210285..4546f00 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -307,7 +307,7 @@ public: bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const { - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); switch(status) { case GL_NO_ERROR: case GL_FRAMEBUFFER_COMPLETE_EXT: @@ -362,8 +362,8 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At // texture dimensions while (glGetError() != GL_NO_ERROR) {} // reset error state - glGenFramebuffersEXT(1, &fbo); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); QT_CHECK_GLERROR(); // init texture @@ -383,7 +383,7 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #endif - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, texture, 0); QT_CHECK_GLERROR(); @@ -397,59 +397,59 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At samples = qBound(1, samples, int(maxSamples)); - glGenRenderbuffersEXT(1, &color_buffer); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, color_buffer); + glGenRenderbuffers(1, &color_buffer); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer); if (glRenderbufferStorageMultisampleEXT) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internal_format, size.width(), size.height()); } else { samples = 0; - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internal_format, + glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format, size.width(), size.height()); } - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, color_buffer); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); if (valid) - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples); + glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples); } if (attachment == QGLFramebufferObject::CombinedDepthStencil && (QGLExtensions::glExtensions & QGLExtensions::PackedDepthStencil)) { // depth and stencil buffer needs another extension - glGenRenderbuffersEXT(1, &depth_stencil_buffer); - Q_ASSERT(!glIsRenderbufferEXT(depth_stencil_buffer)); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer); - Q_ASSERT(glIsRenderbufferEXT(depth_stencil_buffer)); + glGenRenderbuffers(1, &depth_stencil_buffer); + Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer)); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer); + Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); else - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, + glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); GLint i = 0; - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); + glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_buffer); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, + glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_buffer); fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; valid = checkFramebufferStatus(); if (!valid) - glDeleteRenderbuffersEXT(1, &depth_stencil_buffer); + glDeleteRenderbuffers(1, &depth_stencil_buffer); } else if (attachment == QGLFramebufferObject::Depth || attachment == QGLFramebufferObject::CombinedDepthStencil) { - glGenRenderbuffersEXT(1, &depth_stencil_buffer); - Q_ASSERT(!glIsRenderbufferEXT(depth_stencil_buffer)); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil_buffer); - Q_ASSERT(glIsRenderbufferEXT(depth_stencil_buffer)); + glGenRenderbuffers(1, &depth_stencil_buffer); + Q_ASSERT(!glIsRenderbuffer(depth_stencil_buffer)); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_stencil_buffer); + Q_ASSERT(glIsRenderbuffer(depth_stencil_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES #define GL_DEPTH_COMPONENT16 0x81A5 @@ -462,30 +462,30 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At } else { #ifdef QT_OPENGL_ES #define GL_DEPTH_COMPONENT16 0x81A5 - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height()); + glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, size.width(), size.height()); #else - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); + glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } GLint i = 0; - glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i); + glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_stencil_buffer); fbo_attachment = QGLFramebufferObject::Depth; valid = checkFramebufferStatus(); if (!valid) - glDeleteRenderbuffersEXT(1, &depth_stencil_buffer); + glDeleteRenderbuffers(1, &depth_stencil_buffer); } else { fbo_attachment = QGLFramebufferObject::NoAttachment; } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); + glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); if (!valid) { if (color_buffer) - glDeleteRenderbuffersEXT(1, &color_buffer); + glDeleteRenderbuffers(1, &color_buffer); else glDeleteTextures(1, &texture); - glDeleteFramebuffersEXT(1, &fbo); + glDeleteFramebuffers(1, &fbo); } QT_CHECK_GLERROR(); @@ -753,10 +753,10 @@ QGLFramebufferObject::~QGLFramebufferObject() { glDeleteTextures(1, &d->texture); if (d->color_buffer) - glDeleteRenderbuffersEXT(1, &d->color_buffer); + glDeleteRenderbuffers(1, &d->color_buffer); if (d->depth_stencil_buffer) - glDeleteRenderbuffersEXT(1, &d->depth_stencil_buffer); - glDeleteFramebuffersEXT(1, &d->fbo); + glDeleteRenderbuffers(1, &d->depth_stencil_buffer); + glDeleteFramebuffers(1, &d->fbo); } delete d_ptr; } @@ -799,7 +799,7 @@ bool QGLFramebufferObject::bind() return false; Q_D(QGLFramebufferObject); QGL_FUNC_CONTEXT; - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, d->fbo); + glBindFramebuffer(GL_FRAMEBUFFER_EXT, d->fbo); d->bound = d->valid = d->checkFramebufferStatus(); const QGLContext *context = QGLContext::currentContext(); if (d->valid && context) { @@ -835,7 +835,7 @@ bool QGLFramebufferObject::release() if (context) { // Restore the previous setting for stacked framebuffer objects. context->d_ptr->current_fbo = d->previous_fbo; - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, d->previous_fbo); + glBindFramebuffer(GL_FRAMEBUFFER_EXT, d->previous_fbo); d->previous_fbo = 0; } @@ -1144,14 +1144,14 @@ void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const Q const int ty0 = th - (targetRect.top() + targetRect.height()); const int ty1 = th - targetRect.top(); - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source ? source->handle() : 0); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, target ? target->handle() : 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, source ? source->handle() : 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, target ? target->handle() : 0); glBlitFramebufferEXT(sx0, sy0, sx1, sy1, tx0, ty0, tx1, ty1, buffers, filter); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); + glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); } QT_END_NAMESPACE diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 1fa5b47..cb0b4d1 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -280,10 +280,10 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const ensureCreated(); if (!ctx->d_ptr->fbo) - glGenFramebuffersEXT(1, &ctx->d_ptr->fbo); + glGenFramebuffers(1, &ctx->d_ptr->fbo); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, qt_gl_preferredTextureTarget(), m_textureId, 0); const int x0 = 0; @@ -291,7 +291,7 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const const int y0 = 0; const int y1 = m_height; - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); + glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); glDisable(GL_SCISSOR_TEST); @@ -301,7 +301,7 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const GL_NEAREST); if (keepCurrentFboBound) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); + glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); } void QGLPixmapData::swapBuffers() diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 4c2748c..576da12 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -449,14 +449,14 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & const int y0 = h - (rect.top() + rect.height()); const int y1 = h - rect.top(); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); glBlitFramebufferEXT(x0, y0, x1, y1, x0, y0, x1, y1, GL_COLOR_BUFFER_BIT, GL_NEAREST); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); } #if !defined(QT_OPENGL_ES_2) else { -- cgit v0.12 From 3822cd597fc481acb2a4de324c005c23ce8e78cd Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 11 May 2009 09:21:54 +0200 Subject: Fix QWS build breakage QScreen uses QSpanData::setup, so broke because of API change. Reviewed-by: sroedal --- src/gui/embedded/qscreen_qws.cpp | 5 +++-- src/gui/painting/qdrawhelper_p.h | 2 +- src/gui/painting/qpaintengine_raster.cpp | 12 ++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/gui/embedded/qscreen_qws.cpp b/src/gui/embedded/qscreen_qws.cpp index ff48403..a82edbb 100644 --- a/src/gui/embedded/qscreen_qws.cpp +++ b/src/gui/embedded/qscreen_qws.cpp @@ -49,6 +49,7 @@ #include "qpixmap.h" #include "qvarlengtharray.h" #include "qwsdisplay_qws.h" +#include "qpainter.h" #include #include #include @@ -2710,7 +2711,7 @@ void QScreen::compose(int level, const QRegion &exposed, QRegion &blend, default: break; } - spanData.setup(qwsServer->backgroundBrush(), 256); + spanData.setup(qwsServer->backgroundBrush(), 256, QPainter::CompositionMode_SourceOver); spanData.dx = off.x(); spanData.dy = off.y(); } else if (!surface->isBuffered()) { @@ -2775,7 +2776,7 @@ void QScreen::paintBackground(const QRegion &r) rb.prepare(&img); QSpanData spanData; spanData.init(&rb, 0); - spanData.setup(bg, 256); + spanData.setup(bg, 256, QPainter::CompositionMode_Source); spanData.dx = off.x(); spanData.dy = off.y(); Q_ASSERT(spanData.blend); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 586ffe3..019402a 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -294,7 +294,7 @@ struct QSpanData }; void init(QRasterBuffer *rb, const QRasterPaintEngine *pe); - void setup(const QBrush &brush, int alpha, const QRasterPaintEngineState *s); + void setup(const QBrush &brush, int alpha, QPainter::CompositionMode compositionMode); void setupMatrix(const QTransform &matrix, int bilinear); void initTexture(const QImage *image, int alpha, QTextureData::Type = QTextureData::Plain, const QRect &sourceRect = QRect()); void adjustSpanMethods(); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 9237e11..a2ce62e 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -485,12 +485,12 @@ bool QRasterPaintEngine::begin(QPaintDevice *device) d->rasterizer->setClipRect(d->deviceRect); s->penData.init(d->rasterBuffer, this); - s->penData.setup(s->pen.brush(), s->intOpacity, s); + s->penData.setup(s->pen.brush(), s->intOpacity, s->composition_mode); s->stroker = &d->basicStroker; d->basicStroker.setClipRect(d->deviceRect); s->brushData.init(d->rasterBuffer, this); - s->brushData.setup(s->brush, s->intOpacity, s); + s->brushData.setup(s->brush, s->intOpacity, s->composition_mode); d->rasterBuffer->compositionMode = QPainter::CompositionMode_SourceOver; @@ -770,7 +770,7 @@ void QRasterPaintEngine::updatePen(const QPen &pen) s->strokeFlags = 0; s->penData.clip = d->clip(); - s->penData.setup(pen_style == Qt::NoPen ? QBrush() : pen.brush(), s->intOpacity, s); + s->penData.setup(pen_style == Qt::NoPen ? QBrush() : pen.brush(), s->intOpacity, s->composition_mode); if (s->strokeFlags & QRasterPaintEngine::DirtyTransform || pen.brush().transform().type() >= QTransform::TxNone) { @@ -870,7 +870,7 @@ void QRasterPaintEngine::updateBrush(const QBrush &brush) QRasterPaintEngineState *s = state(); // must set clip prior to setup, as setup uses it... s->brushData.clip = d->clip(); - s->brushData.setup(brush, s->intOpacity, s); + s->brushData.setup(brush, s->intOpacity, s->composition_mode); if (s->fillFlags & DirtyTransform || brush.transform().type() >= QTransform::TxNone) d_func()->updateMatrixData(&s->brushData, brush, d->brushMatrix()); @@ -5029,7 +5029,7 @@ void QSpanData::init(QRasterBuffer *rb, const QRasterPaintEngine *pe) extern QImage qt_imageForBrush(int brushStyle, bool invert); -void QSpanData::setup(const QBrush &brush, int alpha, const QRasterPaintEngineState *s) +void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode compositionMode) { Qt::BrushStyle brushStyle = qbrush_style(brush); switch (brushStyle) { @@ -5038,7 +5038,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, const QRasterPaintEngineSt QColor c = qbrush_color(brush); solid.color = PREMUL(ARGB_COMBINE_ALPHA(c.rgba(), alpha)); if ((solid.color & 0xff000000) == 0 - && s->composition_mode == QPainter::CompositionMode_SourceOver) { + && compositionMode == QPainter::CompositionMode_SourceOver) { type = None; } break; -- cgit v0.12 From 98bb706b76936dfc88e8d38db39518a3cdf74b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 13 May 2009 10:01:40 +0200 Subject: Enabled compilation of both GL and GL2 paint engine. Compile both GL and GL2 paint engine on desktop, and choose between them at run-time based on GL version flags. Reviewed-by: Tom --- src/opengl/gl2paintengineex/qglgradientcache.cpp | 8 +++--- src/opengl/gl2paintengineex/qglgradientcache_p.h | 4 +-- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 22 +++++++-------- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 16 +++++------ src/opengl/opengl.pro | 29 +++++++++---------- src/opengl/qgl.cpp | 33 ++++++++++++++-------- src/opengl/qgl_p.h | 15 ++++++++-- src/opengl/qglframebufferobject.cpp | 18 +++++++----- src/opengl/qglpixelbuffer.cpp | 19 +++++++------ src/opengl/qglpixmapfilter.cpp | 15 +--------- src/opengl/qpaintengine_opengl.cpp | 32 ++------------------- src/opengl/qpixmapdata_gl.cpp | 4 --- src/opengl/qwindowsurface_gl.cpp | 18 +++++++----- 13 files changed, 109 insertions(+), 124 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp index b4591b2..59d4bf8 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache.cpp +++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp @@ -44,7 +44,7 @@ #include "qglgradientcache_p.h" -void QGLGradientCache::cleanCache() { +void QGL2GradientCache::cleanCache() { QGLGradientColorTableHash::const_iterator it = cache.constBegin(); for (; it != cache.constEnd(); ++it) { const CacheInfo &cache_info = it.value(); @@ -53,7 +53,7 @@ void QGLGradientCache::cleanCache() { cache.clear(); } -GLuint QGLGradientCache::getBuffer(const QGradient &gradient, qreal opacity, const QGLContext *ctx) +GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity, const QGLContext *ctx) { if (buffer_ctx && !qgl_share_reg()->checkSharing(buffer_ctx, ctx)) cleanCache(); @@ -84,7 +84,7 @@ GLuint QGLGradientCache::getBuffer(const QGradient &gradient, qreal opacity, con } -GLuint QGLGradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity) +GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity) { if (cache.size() == maxCacheSize()) { int elem_to_remove = qrand() % maxCacheSize(); @@ -129,7 +129,7 @@ static inline uint qtToGlColor(uint c) } //TODO: Let GL generate the texture using an FBO -void QGLGradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const +void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const { int pos = 0; QGradientStops s = gradient.stops(); diff --git a/src/opengl/gl2paintengineex/qglgradientcache_p.h b/src/opengl/gl2paintengineex/qglgradientcache_p.h index 346ea13..6acaa00 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache_p.h +++ b/src/opengl/gl2paintengineex/qglgradientcache_p.h @@ -54,7 +54,7 @@ #include #include -class QGLGradientCache : public QObject +class QGL2GradientCache : public QObject { Q_OBJECT struct CacheInfo @@ -71,7 +71,7 @@ class QGLGradientCache : public QObject typedef QMultiHash QGLGradientColorTableHash; public: - QGLGradientCache() : QObject(), buffer_ctx(0) + QGL2GradientCache() : QObject(), buffer_ctx(0) { /* connect(QGLSignalProxy::instance(), diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 1c0d7e0..9f2384d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -240,7 +240,7 @@ void QGL2PaintEngineExPrivate::useSimpleShader() } -Q_GLOBAL_STATIC(QGLGradientCache, qt_opengl_gradient_cache) +Q_GLOBAL_STATIC(QGL2GradientCache, qt_opengl_gradient_cache) void QGL2PaintEngineExPrivate::updateBrushTexture() { @@ -941,7 +941,7 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem Q_D(QGL2PaintEngineEx); ensureActive(); - QOpenGLPaintEngineState *s = state(); + QOpenGL2PaintEngineState *s = state(); const QTextItemInt &ti = static_cast(textItem); @@ -967,7 +967,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte transferMode(TextDrawingMode); Q_Q(QGL2PaintEngineEx); - QOpenGLPaintEngineState *s = q->state(); + QOpenGL2PaintEngineState *s = q->state(); QVarLengthArray positions; QVarLengthArray glyphs; @@ -1364,9 +1364,9 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) Q_D(QGL2PaintEngineEx); - QOpenGLPaintEngineState *s = static_cast(new_state); + QOpenGL2PaintEngineState *s = static_cast(new_state); - QOpenGLPaintEngineState *old_state = state(); + QOpenGL2PaintEngineState *old_state = state(); const bool needsDepthClipUpdate = !old_state || s->clipEnabled != old_state->clipEnabled || (s->clipEnabled && s->clipRegion != old_state->clipRegion); @@ -1386,28 +1386,28 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) QPainterState *QGL2PaintEngineEx::createState(QPainterState *orig) const { - QOpenGLPaintEngineState *s; + QOpenGL2PaintEngineState *s; if (!orig) - s = new QOpenGLPaintEngineState(); + s = new QOpenGL2PaintEngineState(); else - s = new QOpenGLPaintEngineState(*static_cast(orig)); + s = new QOpenGL2PaintEngineState(*static_cast(orig)); return s; } -QOpenGLPaintEngineState::QOpenGLPaintEngineState(QOpenGLPaintEngineState &other) +QOpenGL2PaintEngineState::QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other) : QPainterState(other) { clipRegion = other.clipRegion; hasClipping = other.hasClipping; } -QOpenGLPaintEngineState::QOpenGLPaintEngineState() +QOpenGL2PaintEngineState::QOpenGL2PaintEngineState() { hasClipping = false; } -QOpenGLPaintEngineState::~QOpenGLPaintEngineState() +QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState() { } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index b31f685..76a4fe0 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -58,12 +58,12 @@ class QGL2PaintEngineExPrivate; -class QOpenGLPaintEngineState : public QPainterState +class QOpenGL2PaintEngineState : public QPainterState { public: - QOpenGLPaintEngineState(QOpenGLPaintEngineState &other); - QOpenGLPaintEngineState(); - ~QOpenGLPaintEngineState(); + QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other); + QOpenGL2PaintEngineState(); + ~QOpenGL2PaintEngineState(); QRegion clipRegion; bool hasClipping; @@ -107,11 +107,11 @@ public: // State stuff is just for clipping and ripped off from QGLPaintEngine void setState(QPainterState *s); QPainterState *createState(QPainterState *orig) const; - inline QOpenGLPaintEngineState *state() { - return static_cast(QPaintEngineEx::state()); + inline QOpenGL2PaintEngineState *state() { + return static_cast(QPaintEngineEx::state()); } - inline const QOpenGLPaintEngineState *state() const { - return static_cast(QPaintEngineEx::state()); + inline const QOpenGL2PaintEngineState *state() const { + return static_cast(QPaintEngineEx::state()); } void updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op); diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index cfa9e4f..7eb2503 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -37,24 +37,21 @@ SOURCES += qgl.cpp \ qglpixmapfilter.cpp \ qglshaderprogram.cpp -#!contains(QT_CONFIG, opengles2) { -# HEADERS += qpaintengine_opengl_p.h -# SOURCES += qpaintengine_opengl.cpp -#} +!contains(QT_CONFIG, opengles2) { + HEADERS += qpaintengine_opengl_p.h + SOURCES += qpaintengine_opengl.cpp +} -#contains(QT_CONFIG, opengles2) { - SOURCES += gl2paintengineex/qglgradientcache.cpp \ - gl2paintengineex/qglengineshadermanager.cpp \ - gl2paintengineex/qgl2pexvertexarray.cpp \ - gl2paintengineex/qpaintengineex_opengl2.cpp - - HEADERS += gl2paintengineex/qglgradientcache_p.h \ - gl2paintengineex/qglengineshadermanager_p.h \ - gl2paintengineex/qgl2pexvertexarray_p.h \ - gl2paintengineex/qpaintengineex_opengl2_p.h \ - gl2paintengineex/qglengineshadersource_p.h -#} +SOURCES += gl2paintengineex/qglgradientcache.cpp \ + gl2paintengineex/qglengineshadermanager.cpp \ + gl2paintengineex/qgl2pexvertexarray.cpp \ + gl2paintengineex/qpaintengineex_opengl2.cpp +HEADERS += gl2paintengineex/qglgradientcache_p.h \ + gl2paintengineex/qglengineshadermanager_p.h \ + gl2paintengineex/qgl2pexvertexarray_p.h \ + gl2paintengineex/qpaintengineex_opengl2_p.h \ + gl2paintengineex/qglengineshadersource_p.h x11 { contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles1cl)|contains(QT_CONFIG, opengles2) { diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index ccb6080..779ed9a 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -65,9 +65,9 @@ #include "qimage.h" #include "qgl_p.h" -#if 1 || defined(QT_OPENGL_ES_2) #include "gl2paintengineex/qpaintengineex_opengl2_p.h" -#else + +#ifndef QT_OPENGL_ES_2 #include #endif @@ -2125,9 +2125,6 @@ void QGLContext::deleteTexture(QMacCompatGLuint id) } #endif -// qpaintengine_opengl.cpp -#if !defined(QT_OPENGL_ES_2) -//extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array); void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) { qreal left = r.left(); @@ -2145,9 +2142,17 @@ void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) array[7] = f2vt(bottom); } -#else -void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) {}; -#endif +void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array) +{ + array[0] = f2vt(x1); + array[1] = f2vt(y1); + array[2] = f2vt(x2); + array[3] = f2vt(y1); + array[4] = f2vt(x2); + array[5] = f2vt(y2); + array[6] = f2vt(x1); + array[7] = f2vt(y2); +} static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget) { @@ -4154,9 +4159,9 @@ void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QM } #endif -#if 1 || defined(QT_OPENGL_ES_2) -Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_engine) -#else +Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine) + +#ifndef QT_OPENGL_ES_2 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine) #endif @@ -4179,7 +4184,11 @@ Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine() */ QPaintEngine *QGLWidget::paintEngine() const { - return qt_gl_engine(); +#ifndef QT_OPENGL_ES_2 + if (!qt_gl_preferGL2Engine()) + return qt_gl_engine(); +#endif + return qt_gl_2_engine(); } #ifdef QT3_SUPPORT diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index f7b9392..1513ee8 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -419,6 +419,17 @@ extern QOpenGLPaintEngine* qt_qgl_paint_engine(); extern EGLDisplay qt_qgl_egl_display(); #endif +inline bool qt_gl_preferGL2Engine() +{ +#if defined(QT_OPENGL_ES_2) + return true; +#else + QGLFormat::OpenGLVersionFlags flags = QGLFormat::openGLVersionFlags(); + bool hasOpenGL2 = (flags & QGLFormat::OpenGL_Version_2_0); + return hasOpenGL2 && qgetenv("QT_GL_NO_OPENGL2ENGINE").isEmpty(); +#endif +} + inline GLenum qt_gl_preferredTextureFormat() { return QSysInfo::ByteOrder == QSysInfo::BigEndian ? GL_RGBA : GL_BGRA; @@ -426,16 +437,16 @@ inline GLenum qt_gl_preferredTextureFormat() inline GLenum qt_gl_preferredTextureTarget() { -#if 1 || defined(QT_OPENGL_ES_2) +#if defined(QT_OPENGL_ES_2) return GL_TEXTURE_2D; #else return (QGLExtensions::glExtensions & QGLExtensions::TextureRectangle) + && !qt_gl_preferGL2Engine() ? GL_TEXTURE_RECTANGLE_NV : GL_TEXTURE_2D; #endif } - QT_END_NAMESPACE #endif // QGL_P_H diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index aa5dfc5..87e0dda 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -43,11 +43,12 @@ #include #include -#if 1 || defined(QT_OPENGL_ES_2) #include -#else + +#ifndef QT_OPENGL_ES_2 #include #endif + #include #include #include @@ -896,17 +897,20 @@ QImage QGLFramebufferObject::toImage() const return image; } -#if 1 || defined(QT_OPENGL_ES_2) -Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_paintengine) -#else -Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_paintengine) +Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_2_engine) + +#ifndef QT_OPENGL_ES_2 +Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine) #endif /*! \reimp */ QPaintEngine *QGLFramebufferObject::paintEngine() const { #if !defined(QT_OPENGL_ES_2) - return qt_buffer_paintengine(); + if (qt_gl_preferGL2Engine()) + return qt_buffer_2_engine(); + else + return qt_buffer_engine(); #else return 0; #endif diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 6a207c8..cb24177 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -81,15 +81,15 @@ #include #include -#if 1 || defined(QT_OPENGL_ES_2) #include -#else + +#ifndef QT_OPENGL_ES_2 #include #endif QT_BEGIN_NAMESPACE -#if 0 && !defined(QT_OPENGL_ES_2) +#if !defined(QT_OPENGL_ES_2) extern void qgl_cleanup_glyph_cache(QGLContext *); #else void qgl_cleanup_glyph_cache(QGLContext *) {} @@ -365,17 +365,20 @@ bool QGLPixelBuffer::isValid() const return !d->invalid; } -#if 1 || defined(QT_OPENGL_ES_2) -Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_paintengine) -#else -Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_paintengine) +Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_2_engine) + +#ifndef QT_OPENGL_ES_2 +Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine) #endif /*! \reimp */ QPaintEngine *QGLPixelBuffer::paintEngine() const { #if !defined(QT_OPENGL_ES_2) - return qt_buffer_paintengine(); + if (qt_gl_preferGL2Engine()) + return qt_buffer_2_engine(); + else + return qt_buffer_engine(); #else return 0; #endif diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 5d4d5bf..eb3298b 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -116,21 +116,8 @@ QPixmapFilter *QGLContextPrivate::createPixmapFilter(int type) const return 0; } -#if !defined(QT_OPENGL_ES_2) extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array); -//extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array); -void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array) -{ - array[0] = f2vt(x1); - array[1] = f2vt(y1); - array[2] = f2vt(x2); - array[3] = f2vt(y1); - array[4] = f2vt(x2); - array[5] = f2vt(y2); - array[6] = f2vt(x1); - array[7] = f2vt(y2); -} -#endif +extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array); static void qgl_drawTexture(const QRectF &rect, int tx_width, int tx_height, const QRectF & src) { diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 612168e..9197ebc 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -123,35 +123,6 @@ struct QT_PointF { qreal y; }; -void qt_add_rect_to_array(const QRectF &r, q_vertexType *array) -{ - qreal left = r.left(); - qreal right = r.right(); - qreal top = r.top(); - qreal bottom = r.bottom(); - - array[0] = f2vt(left); - array[1] = f2vt(top); - array[2] = f2vt(right); - array[3] = f2vt(top); - array[4] = f2vt(right); - array[5] = f2vt(bottom); - array[6] = f2vt(left); - array[7] = f2vt(bottom); -} - -void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array) -{ - array[0] = f2vt(x1); - array[1] = f2vt(y1); - array[2] = f2vt(x2); - array[3] = f2vt(y1); - array[4] = f2vt(x2); - array[5] = f2vt(y2); - array[6] = f2vt(x1); - array[7] = f2vt(y2); -} - struct QGLTrapezoid { QGLTrapezoid() @@ -3124,6 +3095,9 @@ QGLTrapezoidMaskGenerator::QGLTrapezoidMaskGenerator(const QPainterPath &path, c { } +extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array); +extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array); + void QGLTrapezoidMaskGenerator::drawMask(const QRect &rect) { #ifdef QT_OPENGL_ES diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index cb0b4d1..89e6749 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -49,11 +49,7 @@ #include #include -#if 1 || defined(QT_OPENGL_ES_2) #include -#else -#include -#endif QT_BEGIN_NAMESPACE diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 576da12..2f111f4 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -69,9 +69,10 @@ #include #include -#if 1 || defined(QT_OPENGL_ES_2) + #include -#else + +#ifndef QT_OPENGL_ES_2 #include #endif @@ -292,17 +293,20 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size(); } -#if 1 || defined(QT_OPENGL_ES_2) -Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_window_surface_paintengine) -#else -Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_paintengine) +Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_window_surface_2_engine) + +#ifndef QT_OPENGL_ES_2 +Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_engine) #endif /*! \reimp */ QPaintEngine *QGLWindowSurface::paintEngine() const { #if !defined(QT_OPENGL_ES_2) - return qt_gl_window_surface_paintengine(); + if (qt_gl_preferGL2Engine()) + return qt_gl_window_surface_2_engine(); + else + return qt_gl_window_surface_engine(); #else return 0; #endif -- cgit v0.12 From b352b0e637ca19591ee122c47ce4a6ab0a26c06b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 13 May 2009 10:56:31 +0200 Subject: Made GL graphics system work with GLES2 w/o FramebufferBlit extension. At the moment, for the GL graphics system to work properly with GLES 2 without the FramebufferBlit extension swapBuffers() needs to preserve the back buffer. --- src/opengl/qwindowsurface_gl.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 2f111f4..c732174 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -303,13 +303,10 @@ Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_engine) QPaintEngine *QGLWindowSurface::paintEngine() const { #if !defined(QT_OPENGL_ES_2) - if (qt_gl_preferGL2Engine()) - return qt_gl_window_surface_2_engine(); - else + if (!qt_gl_preferGL2Engine()) return qt_gl_window_surface_engine(); -#else - return 0; #endif + return qt_gl_window_surface_2_engine(); } int QGLWindowSurface::metric(PaintDeviceMetric m) const @@ -370,6 +367,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & context()->makeCurrent(); if (context()->format().doubleBuffer()) { +#if !defined(QT_OPENGL_ES_2) glBindTexture(target, d_ptr->tex_id); QVector rects = d_ptr->paintedRegion.rects(); @@ -386,7 +384,6 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion; -#if !defined(QT_OPENGL_ES_2) if (!dirtyRegion.isEmpty()) { context()->makeCurrent(); @@ -522,7 +519,12 @@ void QGLWindowSurface::updateGeometry() return; } - if ((QGLExtensions::glExtensions & QGLExtensions::FramebufferObject) && (d_ptr->fbo || !d_ptr->tried_fbo)) { + if ((QGLExtensions::glExtensions & QGLExtensions::FramebufferObject) +#ifdef QT_OPENGL_ES_2 + && (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) +#endif + && (d_ptr->fbo || !d_ptr->tried_fbo)) + { d_ptr->tried_fbo = true; hijackWindow(window()); QGLContext *ctx = reinterpret_cast(window()->d_func()->extraData()->glContext); @@ -551,6 +553,7 @@ void QGLWindowSurface::updateGeometry() } } +#if !defined(QT_OPENGL_ES_2) if (d_ptr->pb || !d_ptr->tried_pb) { d_ptr->tried_pb = true; @@ -577,7 +580,6 @@ void QGLWindowSurface::updateGeometry() glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(target, 0); -#if !defined(QT_OPENGL_ES_2) glMatrixMode(GL_PROJECTION); glLoadIdentity(); #ifndef QT_OPENGL_ES @@ -585,7 +587,6 @@ void QGLWindowSurface::updateGeometry() #else glOrthof(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999); #endif -#endif // !defined(QT_OPENGL_ES_2) d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true; return; @@ -595,7 +596,7 @@ void QGLWindowSurface::updateGeometry() d_ptr->pb = 0; } } - +#endif // !defined(QT_OPENGL_ES_2) hijackWindow(window()); QGLContext *ctx = reinterpret_cast(window()->d_func()->extraData()->glContext); -- cgit v0.12 From c8c5becc81679eb8a9a0f8baa454bc43fd3cccf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 13 May 2009 14:47:54 +0200 Subject: Reverted use of GL 2 engine as default on desktop. Using GL 2 as default engine breaks the use cases where OpenGL commands are inter-mixed with QPainter commands, such as when using raw OpenGL in graphicsview. For now we'll use the old OpenGL engine for QGLWidget, QGLPixelBuffer, and QGLFramebufferObject on desktop, and the OpenGL 2 paint engine when the OpenGL graphics system is used. Reviewed-by: Trond --- src/opengl/qgl.cpp | 4 ++-- src/opengl/qgl_p.h | 5 ++--- src/opengl/qglframebufferobject.cpp | 3 ++- src/opengl/qglpixelbuffer.cpp | 2 +- src/opengl/qpixmapdata_gl.cpp | 8 ++++---- src/opengl/qwindowsurface_gl.cpp | 20 ++++---------------- 6 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 779ed9a..12f781e 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1366,7 +1366,7 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp int w = size.width(); int h = size.height(); #if !defined(QT_OPENGL_ES_2) //### glGetTexImage not in GL ES 2.0, need to do something else here! - glGetTexImage(qt_gl_preferredTextureTarget(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); #endif convertFromGLImage(img, w, h, alpha_format, include_alpha); return img; @@ -1971,7 +1971,7 @@ GLuint QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLin { Q_Q(QGLContext); QPixmapData *pd = pixmap.pixmapData(); - if (target == qt_gl_preferredTextureTarget() && pd->classId() == QPixmapData::OpenGLClass) { + if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) { const QGLPixmapData *data = static_cast(pd); if (data->isValidContext(q)) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 1513ee8..a294af9 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -424,9 +424,8 @@ inline bool qt_gl_preferGL2Engine() #if defined(QT_OPENGL_ES_2) return true; #else - QGLFormat::OpenGLVersionFlags flags = QGLFormat::openGLVersionFlags(); - bool hasOpenGL2 = (flags & QGLFormat::OpenGL_Version_2_0); - return hasOpenGL2 && qgetenv("QT_GL_NO_OPENGL2ENGINE").isEmpty(); + return (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) + && !qgetenv("QT_GL_USE_OPENGL2ENGINE").isEmpty(); #endif } diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 87e0dda..5f106ff 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -906,8 +906,9 @@ Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine) /*! \reimp */ QPaintEngine *QGLFramebufferObject::paintEngine() const { + Q_D(const QGLFramebufferObject); #if !defined(QT_OPENGL_ES_2) - if (qt_gl_preferGL2Engine()) + if (d->ctx->d_func()->internal_context || qt_gl_preferGL2Engine()) return qt_buffer_2_engine(); else return qt_buffer_engine(); diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index cb24177..00b58d3 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -375,7 +375,7 @@ Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine) QPaintEngine *QGLPixelBuffer::paintEngine() const { #if !defined(QT_OPENGL_ES_2) - if (qt_gl_preferGL2Engine()) + if (d_ptr->qctx->d_func()->internal_context || qt_gl_preferGL2Engine()) return qt_buffer_2_engine(); else return qt_buffer_engine(); diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 89e6749..e3af864 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -160,7 +160,7 @@ void QGLPixmapData::ensureCreated() const m_ctx = ctx; const GLenum format = qt_gl_preferredTextureFormat(); - const GLenum target = qt_gl_preferredTextureTarget(); + const GLenum target = GL_TEXTURE_2D; if (!m_textureId) { glGenTextures(1, &m_textureId); @@ -252,7 +252,7 @@ QImage QGLPixmapData::toImage() const QGLShareContextScope ctx(qt_gl_share_widget()->context()); extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); - glBindTexture(qt_gl_preferredTextureTarget(), m_textureId); + glBindTexture(GL_TEXTURE_2D, m_textureId); return qt_gl_read_texture(QSize(m_width, m_height), true, true); } @@ -280,7 +280,7 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - qt_gl_preferredTextureTarget(), m_textureId, 0); + GL_TEXTURE_2D, m_textureId, 0); const int x0 = 0; const int x1 = m_width; @@ -398,7 +398,7 @@ GLuint QGLPixmapData::bind(bool copyBack) const ensureCreated(); GLuint id = m_textureId; - glBindTexture(qt_gl_preferredTextureTarget(), id); + glBindTexture(GL_TEXTURE_2D, id); return id; } diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index c732174..6fce3e3 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -72,10 +72,6 @@ #include -#ifndef QT_OPENGL_ES_2 -#include -#endif - #ifndef GLX_ARB_multisample #define GLX_SAMPLE_BUFFERS_ARB 100000 #define GLX_SAMPLES_ARB 100001 @@ -295,17 +291,9 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_window_surface_2_engine) -#ifndef QT_OPENGL_ES_2 -Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_engine) -#endif - /*! \reimp */ QPaintEngine *QGLWindowSurface::paintEngine() const { -#if !defined(QT_OPENGL_ES_2) - if (!qt_gl_preferGL2Engine()) - return qt_gl_window_surface_engine(); -#endif return qt_gl_window_surface_2_engine(); } @@ -361,7 +349,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & QPoint wOffset = qt_qwidget_data(parent)->wrect.topLeft(); QRect rect = br.translated(-offset - wOffset); - const GLenum target = qt_gl_preferredTextureTarget(); + const GLenum target = GL_TEXTURE_2D; if (context()) { context()->makeCurrent(); @@ -502,7 +490,7 @@ void QGLWindowSurface::updateGeometry() { QRect rect = QWindowSurface::geometry(); - const GLenum target = qt_gl_preferredTextureTarget(); + const GLenum target = GL_TEXTURE_2D; if (rect.width() <= 0 || rect.height() <= 0) return; @@ -643,7 +631,7 @@ bool QGLWindowSurface::scroll(const QRegion &area, int dx, int dy) return true; #endif - const GLenum target = qt_gl_preferredTextureTarget(); + const GLenum target = GL_TEXTURE_2D; glBindTexture(target, d_ptr->tex_id); glCopyTexImage2D(target, 0, GL_RGBA, br.x(), d_ptr->pb->height() - (br.y() + br.height()), br.width(), br.height(), 0); @@ -656,7 +644,7 @@ bool QGLWindowSurface::scroll(const QRegion &area, int dx, int dy) static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br) { - const GLenum target = qt_gl_preferredTextureTarget(); + const GLenum target = GL_TEXTURE_2D; QRectF src = br.isEmpty() ? QRectF(QPointF(), texSize) : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size()); -- cgit v0.12 From 521c5cc3910bffe566e0fb653041f159ecb5b6d5 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 14 May 2009 10:51:46 +0200 Subject: Make QtOpenGL compile on OpenGL ES 1.1 again --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 4 +- src/opengl/opengl.pro | 41 ++++++++------ src/opengl/qgl.cpp | 65 +++++++++++++++++----- src/opengl/qgl_p.h | 17 +++++- src/opengl/qglextensions_p.h | 5 +- src/opengl/qglframebufferobject.cpp | 10 +++- src/opengl/qglpixelbuffer.cpp | 10 +++- src/opengl/qpaintengine_opengl.cpp | 9 ++- 8 files changed, 116 insertions(+), 45 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 9f2384d..caf744a 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1331,10 +1331,10 @@ void QGL2PaintEngineExPrivate::updateDepthClip() return; } - glClearDepthf(0x0); + glClearDepth(0x0); glDepthMask(true); glClear(GL_DEPTH_BUFFER_BIT); - glClearDepthf(0x1); + glClearDepth(0x1); glEnable(GL_SCISSOR_TEST); for (int i = 0; i < rects.size(); ++i) { diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 7eb2503..73af174 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -13,20 +13,14 @@ include(../qbase.pri) !win32:!embedded:!mac:CONFIG += x11 contains(QT_CONFIG, opengl):CONFIG += opengl contains(QT_CONFIG, opengles1):CONFIG += opengles1 +contains(QT_CONFIG, opengles1):CONFIG += opengles1cl contains(QT_CONFIG, opengles2):CONFIG += opengles2 -#!contains(QT_CONFIG, opengles2) { - HEADERS += qgraphicssystem_gl_p.h qwindowsurface_gl_p.h qpixmapdata_gl_p.h - SOURCES += qgraphicssystem_gl.cpp qwindowsurface_gl.cpp qpixmapdata_gl.cpp -#} - HEADERS += qgl.h \ qgl_p.h \ qglcolormap.h \ qglpixelbuffer.h \ qglframebufferobject.h \ - qglpixmapfilter_p.h \ - qglshaderprogram.h \ qglextensions_p.h SOURCES += qgl.cpp \ @@ -34,24 +28,35 @@ SOURCES += qgl.cpp \ qglpixelbuffer.cpp \ qglframebufferobject.cpp \ qglextensions.cpp \ - qglpixmapfilter.cpp \ - qglshaderprogram.cpp !contains(QT_CONFIG, opengles2) { HEADERS += qpaintengine_opengl_p.h SOURCES += qpaintengine_opengl.cpp } -SOURCES += gl2paintengineex/qglgradientcache.cpp \ - gl2paintengineex/qglengineshadermanager.cpp \ - gl2paintengineex/qgl2pexvertexarray.cpp \ - gl2paintengineex/qpaintengineex_opengl2.cpp +!contains(QT_CONFIG, opengles1):!contains(QT_CONFIG, opengles1cl) { + HEADERS += qglshaderprogram.h \ + qglpixmapfilter_p.h \ + qgraphicssystem_gl_p.h \ + qwindowsurface_gl_p.h \ + qpixmapdata_gl_p.h \ + gl2paintengineex/qglgradientcache_p.h \ + gl2paintengineex/qglengineshadermanager_p.h \ + gl2paintengineex/qgl2pexvertexarray_p.h \ + gl2paintengineex/qpaintengineex_opengl2_p.h \ + gl2paintengineex/qglengineshadersource_p.h + + SOURCES += qglshaderprogram.cpp \ + qglpixmapfilter.cpp \ + qgraphicssystem_gl.cpp \ + qwindowsurface_gl.cpp \ + qpixmapdata_gl.cpp \ + gl2paintengineex/qglgradientcache.cpp \ + gl2paintengineex/qglengineshadermanager.cpp \ + gl2paintengineex/qgl2pexvertexarray.cpp \ + gl2paintengineex/qpaintengineex_opengl2.cpp -HEADERS += gl2paintengineex/qglgradientcache_p.h \ - gl2paintengineex/qglengineshadermanager_p.h \ - gl2paintengineex/qgl2pexvertexarray_p.h \ - gl2paintengineex/qpaintengineex_opengl2_p.h \ - gl2paintengineex/qglengineshadersource_p.h +} x11 { contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles1cl)|contains(QT_CONFIG, opengles2) { diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 12f781e..a1f81ca 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1365,7 +1365,8 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp QImage img(size, alpha_format ? QImage::Format_ARGB32 : QImage::Format_RGB32); int w = size.width(); int h = size.height(); -#if !defined(QT_OPENGL_ES_2) //### glGetTexImage not in GL ES 2.0, need to do something else here! +#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) + //### glGetTexImage not in GL ES 2.0, need to do something else here! glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); #endif convertFromGLImage(img, w, h, alpha_format, include_alpha); @@ -1971,12 +1972,14 @@ GLuint QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLin { Q_Q(QGLContext); QPixmapData *pd = pixmap.pixmapData(); +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) { const QGLPixmapData *data = static_cast(pd); if (data->isValidContext(q)) return data->bind(); } +#endif const qint64 key = pixmap.cacheKey(); GLuint id; @@ -4159,7 +4162,9 @@ void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QM } #endif +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_2_engine) +#endif #ifndef QT_OPENGL_ES_2 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_engine) @@ -4184,11 +4189,16 @@ Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine() */ QPaintEngine *QGLWidget::paintEngine() const { -#ifndef QT_OPENGL_ES_2 +#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL) + return qt_gl_engine(); +#elif defined(QT_OPENGL_ES_2) + return qt_gl_2_engine(); +#else if (!qt_gl_preferGL2Engine()) return qt_gl_engine(); + else + return qt_gl_2_engine(); #endif - return qt_gl_2_engine(); } #ifdef QT3_SUPPORT @@ -4338,6 +4348,7 @@ void QGLDrawable::setDevice(QPaintDevice *pdev) wsurf = 0; #endif +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) if (pdev->devType() == QInternal::Pixmap) { QPixmapData *data = static_cast(pdev)->pixmapData(); Q_ASSERT(data->classId() == QPixmapData::OpenGLClass); @@ -4345,6 +4356,9 @@ void QGLDrawable::setDevice(QPaintDevice *pdev) fbo = pixmapData->fbo(); } +#else + Q_ASSERT(pdev->devType() != QInternal::Pixmap); +#endif if (pdev->devType() == QInternal::Widget) widget = static_cast(pdev); @@ -4352,10 +4366,11 @@ void QGLDrawable::setDevice(QPaintDevice *pdev) buffer = static_cast(pdev); else if (pdev->devType() == QInternal::FramebufferObject) fbo = static_cast(pdev); - else if (pdev->devType() == QInternal::UnknownDevice) #ifdef Q_WS_QWS + else if (pdev->devType() == QInternal::UnknownDevice) wsurf = static_cast(pdev)->windowSurface(); -#else +#elif !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) + else if (pdev->devType() == QInternal::UnknownDevice) wsurf = static_cast(pdev); #endif } @@ -4365,8 +4380,10 @@ void QGLDrawable::swapBuffers() if (widget) { if (widget->autoBufferSwap()) widget->swapBuffers(); +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) } else if (pixmapData) { pixmapData->swapBuffers(); +#endif } else { glFlush(); } @@ -4374,14 +4391,18 @@ void QGLDrawable::swapBuffers() void QGLDrawable::makeCurrent() { - if (pixmapData) - pixmapData->makeCurrent(); - else if (widget) + if (widget) widget->makeCurrent(); +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) + else if (pixmapData) + pixmapData->makeCurrent(); +#endif else if (buffer) buffer->makeCurrent(); +#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)) else if (wsurf) wsurf->context()->makeCurrent(); +#endif else if (fbo) { wasBound = fbo->isBound(); if (!wasBound) @@ -4389,18 +4410,25 @@ void QGLDrawable::makeCurrent() } } +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) QGLPixmapData *QGLDrawable::copyOnBegin() const { if (!pixmapData || pixmapData->isUninitialized()) return 0; return pixmapData; } +#endif void QGLDrawable::doneCurrent() { - if (pixmapData) +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) + if (pixmapData) { pixmapData->doneCurrent(); - else if (fbo && !wasBound) + return; + } +#endif + + if (fbo && !wasBound) fbo->release(); } @@ -4409,19 +4437,22 @@ QSize QGLDrawable::size() const if (widget) { return QSize(widget->d_func()->glcx->device()->width(), widget->d_func()->glcx->device()->height()); +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) } else if (pixmapData) { return pixmapData->size(); +#endif } else if (buffer) { return buffer->size(); } else if (fbo) { return fbo->size(); - } else if (wsurf) { + } #ifdef Q_WS_QWS + else if (wsurf) return wsurf->window()->frameSize(); -#else +#elif !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) + else if (wsurf) return QSize(wsurf->width(), wsurf->height()); #endif - } return QSize(); } @@ -4431,8 +4462,10 @@ QGLFormat QGLDrawable::format() const return widget->format(); else if (buffer) return buffer->format(); +#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)) else if (wsurf) return wsurf->context()->format(); +#endif else if (fbo && QGLContext::currentContext()) { QGLFormat fmt = QGLContext::currentContext()->format(); fmt.setStencil(fbo->attachment() == QGLFramebufferObject::CombinedDepthStencil); @@ -4451,8 +4484,10 @@ GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format return buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, true); else if (fbo && QGLContext::currentContext()) return const_cast(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, true); +#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)) else if (wsurf) return wsurf->context()->d_func()->bindTexture(image, target, format, true); +#endif return 0; } @@ -4464,8 +4499,10 @@ GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint form return buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, true); else if (fbo && QGLContext::currentContext()) return const_cast(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, true); +#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)) else if (wsurf) return wsurf->context()->d_func()->bindTexture(pixmap, target, format, true); +#endif return 0; } @@ -4484,8 +4521,10 @@ QGLContext *QGLDrawable::context() const return buffer->d_func()->qctx; else if (fbo) return const_cast(QGLContext::currentContext()); +#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)) else if (wsurf) return wsurf->context(); +#endif return 0; } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index a294af9..b421eee 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -60,7 +60,10 @@ #include "QtCore/qthreadstorage.h" #include "QtCore/qhash.h" #include "private/qwidget_p.h" + +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) #include "private/qpixmapdata_gl_p.h" +#endif #ifndef QT_OPENGL_ES_1_CL #define q_vertexType float @@ -293,7 +296,12 @@ class QGLWindowSurface; class QGLDrawable { public: QGLDrawable() : widget(0), buffer(0), fbo(0) - , wsurf(0), pixmapData(0) +#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)) + , wsurf(0) +#endif +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) + , pixmapData(0) +#endif {} void setDevice(QPaintDevice *pdev); void swapBuffers(); @@ -307,7 +315,9 @@ public: QGLContext *context() const; bool autoFillBackground() const; +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) QGLPixmapData *copyOnBegin() const; +#endif private: bool wasBound; @@ -316,10 +326,13 @@ private: QGLFramebufferObject *fbo; #ifdef Q_WS_QWS QWSGLWindowSurface *wsurf; -#else +#elif !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) QGLWindowSurface *wsurf; #endif + +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) QGLPixmapData *pixmapData; +#endif }; // GL extension definitions diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 46047ef..d6edfb6 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -705,7 +705,10 @@ struct QGLExtensionFuncs #if !defined(QT_OPENGL_ES_2) #define glStencilOpSeparate QGLContextPrivate::qt_get_extension_funcs(ctx).qt_glStencilOpSeparate -#define glClearDepthf(x) glClearDepth(GLdouble(x)) +#endif + +#if defined(QT_OPENGL_ES_2) +#define glClearDepth glClearDepthf #endif extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx); diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 5f106ff..f6857ac 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -897,7 +897,9 @@ QImage QGLFramebufferObject::toImage() const return image; } +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_2_engine) +#endif #ifndef QT_OPENGL_ES_2 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine) @@ -906,14 +908,16 @@ Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine) /*! \reimp */ QPaintEngine *QGLFramebufferObject::paintEngine() const { +#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL) + return qt_buffer_engine(); +#elif defined(QT_OPENGL_ES_2) + return qt_buffer_2_engine(); +#else Q_D(const QGLFramebufferObject); -#if !defined(QT_OPENGL_ES_2) if (d->ctx->d_func()->internal_context || qt_gl_preferGL2Engine()) return qt_buffer_2_engine(); else return qt_buffer_engine(); -#else - return 0; #endif } diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 00b58d3..ce7e9bd 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -365,7 +365,9 @@ bool QGLPixelBuffer::isValid() const return !d->invalid; } +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_buffer_2_engine) +#endif #ifndef QT_OPENGL_ES_2 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine) @@ -374,13 +376,15 @@ Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_engine) /*! \reimp */ QPaintEngine *QGLPixelBuffer::paintEngine() const { -#if !defined(QT_OPENGL_ES_2) +#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL) + return qt_buffer_engine(); +#elif defined(QT_OPENGL_ES_2) + return qt_buffer_2_engine(); +#else if (d_ptr->qctx->d_func()->internal_context || qt_gl_preferGL2Engine()) return qt_buffer_2_engine(); else return qt_buffer_engine(); -#else - return 0; #endif } diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 0f447d3..d28a495 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -2255,11 +2255,12 @@ void QOpenGLPaintEnginePrivate::updateDepthClip() return; } -#ifndef QT_OPENGL_ES - glClearDepth(0.0f); -#else +#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_ES_1_CL) glClearDepthf(0.0f); +#else + glClearDepth(0.0f); #endif + glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glClear(GL_DEPTH_BUFFER_BIT); @@ -5580,9 +5581,11 @@ void QOpenGLPaintEnginePrivate::ensureDrawableTexture() QPixmapFilter *QOpenGLPaintEngine::createPixmapFilter(int type) const { +#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) if (QGLContext::currentContext()) return QGLContext::currentContext()->d_func()->createPixmapFilter(type); else +#endif return 0; } -- cgit v0.12 From 889316a3f57b57160e2a08fc41def774d56e288c Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 14 May 2009 15:53:44 +0200 Subject: Start work on docs for Stickman example --- examples/animation/stickman/lifecycle.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/animation/stickman/lifecycle.cpp b/examples/animation/stickman/lifecycle.cpp index 423d7ad..6b69a26 100644 --- a/examples/animation/stickman/lifecycle.cpp +++ b/examples/animation/stickman/lifecycle.cpp @@ -141,9 +141,10 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) m_alive->setInitialState(m_idle); // Lightning strikes at random +//! [0] m_alive->addTransition(new LightningStrikesTransition(lightningBlink)); - //m_alive->addTransition(new KeyPressTransition(m_keyReceiver, Qt::Key_L, lightningBlink)); connectByAnimation(lightningBlink, m_dead, new QSignalTransition(timer, SIGNAL(timeout()))); +//! [0] m_machine->setInitialState(m_alive); } @@ -159,8 +160,8 @@ void LifeCycle::start() m_machine->start(); } -void LifeCycle::connectByAnimation(QState *s1, QAbstractState *s2, - QAbstractTransition *transition) +//! [1] +void LifeCycle::connectByAnimation(QState *s1, QAbstractState *s2, QAbstractTransition *transition) { if (transition == 0) { transition = s1->addTransition(s2); @@ -170,6 +171,7 @@ void LifeCycle::connectByAnimation(QState *s1, QAbstractState *s2, } transition->addAnimation(m_animationGroup); } +//! [1] void LifeCycle::addActivity(const QString &fileName, Qt::Key key) { -- cgit v0.12 From 9400e522d7b89025157657ec87fb1631fc6bf4de Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 14 May 2009 16:50:23 +0200 Subject: Remove the connectByAnimation() function and add some documentation for the Stickman example The connectByAnimation() function is no longer needed since we have default animations. The docs are unfinished. --- doc/src/examples/stickman.qdoc | 115 ++++++++++++++++++++++++++++++ doc/src/images/stickman-example.png | Bin 0 -> 18867 bytes doc/src/images/stickman-example1.png | Bin 0 -> 8311 bytes examples/animation/stickman/lifecycle.cpp | 48 ++++++------- examples/animation/stickman/lifecycle.h | 2 - 5 files changed, 137 insertions(+), 28 deletions(-) create mode 100644 doc/src/examples/stickman.qdoc create mode 100644 doc/src/images/stickman-example.png create mode 100644 doc/src/images/stickman-example1.png diff --git a/doc/src/examples/stickman.qdoc b/doc/src/examples/stickman.qdoc new file mode 100644 index 0000000..0313c81 --- /dev/null +++ b/doc/src/examples/stickman.qdoc @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example animation/stickman + \title Stickman Example + + The Stickman example shows how to animate transitions in a state machine to implement key frame + animations. + + \image stickman-example.png + + In this example, we will write a small application which animates the joints in a skeleton and + projects a stickman figure on top. The stickman can be either "alive" or "dead", and when in the + "alive" state, he can be performing different actions defined by key frame animations. + + Animations are implemented as composite states. Each child state of the animation state + represents a frame in the animation by setting the position of each joint in the stickman's + skeleton to the positions defined for the particular frame. The frames are then bound together + with animated transitions that trigger on the source state's polished() signal. Thus, the + machine will enter the state representing the next state in the animation immediately after it + has finished animating into the previous frame. + + \image stickman-example1.png + + The states for an animation is constructed by reading a custom animation file format and + creating states that assign values to the the "position" properties of each of the nodes in the + skeleton graph. + + \snippet examples/animation/stickman/lifecycle.cpp 1 + + The states are then bound together with signal transitions that listen to the polished() signal. + + \snippet examples/animation/stickman/lifecycle.cpp 2 + + The last frame state is given a transition to the first one, so that the animation will loop + until it is interrupted when a transition out from the animation state is taken. To get smooth + animations between the different key frames, we set a default animation on the state machine. + This is a parallel animation group which contain animations for all the "position" properties + and will be selected by default when taking any transition that leads into a state that assigns + values to these properties. + + \snippet examples/animation/stickman/lifecycle.cpp 3 + + Several such animation states are constructed, and are placed together as children of a top + level "alive" state which represents the stickman life cycle. Transitions go from the parent + state to the child state to ensure that each of the child states inherit them. + + \image stickman-example2.png + + This saves us the effort of connect every state to every state with identical transitions. The + state machine makes sure that transitions between the key frame animations are also smooth by + applying the default animation when interrupting one and starting another. + + Finally, there is a transition out from the "alive" state and into the "dead" state. This is + a custom transition type called LightningStrikesTransition which samples every second and + triggers at random (one out of fifty times on average.) + + \snippet examples/animation/stickman/lifecycle.cpp 4 + + When it triggers, the machine will first enter a "lightningStrike" state which uses a timer to + pause for a brief period of time while the background color of the scene is white. This gives us + a flash effect when the lightning strikes. + + \snippet examples/animation/stickman/lifecycle.cpp 5 + + We start and stop a QTimer object when entering and exiting the state. Then we transition into + the "dead" state when the timer times out. + + \snippet examples/animation/stickman/lifecycle.cpp 0 + + When the machine is in the "dead" state, it will be unresponsive. This is because the "dead" + state has no transitions leading out. + + \image stickman-example3.png + +*/ diff --git a/doc/src/images/stickman-example.png b/doc/src/images/stickman-example.png new file mode 100644 index 0000000..a40f37b Binary files /dev/null and b/doc/src/images/stickman-example.png differ diff --git a/doc/src/images/stickman-example1.png b/doc/src/images/stickman-example1.png new file mode 100644 index 0000000..7b9a5b8 Binary files /dev/null and b/doc/src/images/stickman-example1.png differ diff --git a/examples/animation/stickman/lifecycle.cpp b/examples/animation/stickman/lifecycle.cpp index 6b69a26..1feb31d 100644 --- a/examples/animation/stickman/lifecycle.cpp +++ b/examples/animation/stickman/lifecycle.cpp @@ -82,6 +82,7 @@ private: Qt::Key m_key; }; +//! [4] class LightningStrikesTransition: public QEventTransition { public: @@ -97,6 +98,7 @@ public: return QEventTransition::eventTest(e) && ((qrand() % 50) == 0); } }; +//! [4] LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) : m_stickMan(stickMan), m_keyReceiver(keyReceiver) @@ -110,7 +112,10 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) } // Set up intial state graph +//! [3] m_machine = new QStateMachine(); + m_machine->addDefaultAnimation(m_animationGroup); +//! [3] m_alive = new QState(m_machine->rootState()); m_alive->setObjectName("alive"); @@ -122,11 +127,13 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) lightningBlink->assignProperty(m_stickMan, "fillColor", Qt::white); lightningBlink->assignProperty(m_stickMan, "isDead", true); +//! [5] QTimer *timer = new QTimer(lightningBlink); timer->setSingleShot(true); timer->setInterval(100); QObject::connect(lightningBlink, SIGNAL(entered()), timer, SLOT(start())); QObject::connect(lightningBlink, SIGNAL(exited()), timer, SLOT(stop())); +//! [5] m_dead = new QState(m_machine->rootState()); m_dead->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::black); @@ -141,9 +148,9 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) m_alive->setInitialState(m_idle); // Lightning strikes at random -//! [0] m_alive->addTransition(new LightningStrikesTransition(lightningBlink)); - connectByAnimation(lightningBlink, m_dead, new QSignalTransition(timer, SIGNAL(timeout()))); +//! [0] + lightningBlink->addTransition(timer, SIGNAL(timeout()), m_dead); //! [0] m_machine->setInitialState(m_alive); @@ -160,23 +167,10 @@ void LifeCycle::start() m_machine->start(); } -//! [1] -void LifeCycle::connectByAnimation(QState *s1, QAbstractState *s2, QAbstractTransition *transition) -{ - if (transition == 0) { - transition = s1->addTransition(s2); - } else { - transition->setTargetState(s2); - s1->addTransition(transition); - } - transition->addAnimation(m_animationGroup); -} -//! [1] - void LifeCycle::addActivity(const QString &fileName, Qt::Key key) { QState *state = makeState(m_alive, fileName); - connectByAnimation(m_alive, state, new KeyPressTransition(m_keyReceiver, key)); + m_alive->addTransition(new KeyPressTransition(m_keyReceiver, key, state)); } QState *LifeCycle::makeState(QState *parentState, const QString &animationFileName) @@ -193,26 +187,28 @@ QState *LifeCycle::makeState(QState *parentState, const QString &animationFileNa const int frameCount = animation.totalFrames(); QState *previousState = 0; for (int i=0; isetObjectName(QString::fromLatin1("frame %0").arg(i)); - animation.setCurrentFrame(i); + +//! [1] + QState *frameState = new QState(topLevel); const int nodeCount = animation.nodeCount(); for (int j=0; jassignProperty(m_stickMan->node(j), "position", animation.nodePos(j)); +//! [1] - if (previousState == 0) { + frameState->setObjectName(QString::fromLatin1("frame %0").arg(i)); + if (previousState == 0) topLevel->setInitialState(frameState); - } else { - connectByAnimation(previousState, frameState, - new QSignalTransition(previousState, SIGNAL(polished()))); - } + else +//! [2] + previousState->addTransition(previousState, SIGNAL(polished()), frameState); +//! [2] + previousState = frameState; } // Loop - connectByAnimation(previousState, topLevel->initialState(), - new QSignalTransition(previousState, SIGNAL(polished()))); + previousState->addTransition(previousState, SIGNAL(polished()), topLevel->initialState()); return topLevel; diff --git a/examples/animation/stickman/lifecycle.h b/examples/animation/stickman/lifecycle.h index e520402..8fd0fb2 100644 --- a/examples/animation/stickman/lifecycle.h +++ b/examples/animation/stickman/lifecycle.h @@ -63,8 +63,6 @@ public: void start(); private: - void connectByAnimation(QState *s1, QAbstractState *s2, - QAbstractTransition *transition = 0); QState *makeState(QState *parentState, const QString &animationFileName); StickMan *m_stickMan; -- cgit v0.12 From 7f0b4d3b99bb767724a09234768104e18aa52b0e Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 15 May 2009 10:54:27 +0200 Subject: Fix GL2 paint engine builds on Big-endian machines Reviewed-by: Trond --- src/opengl/gl2paintengineex/qglgradientcache.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp index 59d4bf8..2239c2f 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache.cpp +++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp @@ -109,21 +109,18 @@ GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gra } -// GL's expects pixels in RGBA, bin-endian (ABGR on x86). -// Qt stores in ARGB using whatever byte-order the mancine uses. +// GL's expects pixels in RGBA (when using GL_RGBA), bin-endian (ABGR on x86). +// Qt always stores in ARGB reguardless of the byte-order the mancine uses. static inline uint qtToGlColor(uint c) { uint o; #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - o = c & 0xFF00FF00; // alpha & green already in the right place - o |= (c >> 16) & 0x000000FF; // red - o |= (c << 16) & 0x00FF0000; // blue - + o = (c & 0xff00ff00) // alpha & green already in the right place + | ((c >> 16) & 0x000000ff) // red + | ((c << 16) & 0x00ff0000); // blue #else //Q_BIG_ENDIAN - o = c & 0x00FF00FF; // alpha & green already in the right place - o |= (c << 16) & 0xFF000000; // red - o |= (c >> 16) & 0x0000FF00; // blue -#error big endian not tested with QGLGraphicsContext + o = (c << 8) + | ((c >> 24) & 0x000000ff); #endif // Q_BYTE_ORDER return o; } @@ -136,7 +133,7 @@ void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, ui QVector colors(s.size()); for (int i = 0; i < s.size(); ++i) - colors[i] = s[i].second.rgba(); // Qt LIES! It returns ARGB + colors[i] = s[i].second.rgba(); // Qt LIES! It returns ARGB (on little-endian AND on big-endian) bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation); -- cgit v0.12 From b8058b594534050909cf0dfc6b4be2a1b6a4dc1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 15 May 2009 13:52:55 +0200 Subject: Prevented QClipData related crashes. --- src/gui/painting/qpaintengine_raster.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 87e9283..0e8f50a 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4344,6 +4344,7 @@ void QClipData::initialize() m_clipLines = (ClipLine *)calloc(sizeof(ClipLine), clipSpanHeight); m_spans = (QSpan *)malloc(clipSpanHeight*sizeof(QSpan)); + allocated = clipSpanHeight; if (hasRectClip) { int y = 0; @@ -4388,6 +4389,7 @@ void QClipData::initialize() int y = 0; int firstInBand = 0; + count = 0; while (firstInBand < numRects) { const int currMinY = rects.at(firstInBand).y(); const int currMaxY = currMinY + rects.at(firstInBand).height(); @@ -4502,7 +4504,7 @@ void QClipData::setClipRect(const QRect &rect) ymax = qMin(rect.y() + rect.height(), clipSpanHeight); if (m_spans) { - delete m_spans; + free(m_spans); m_spans = 0; } @@ -4532,7 +4534,7 @@ void QClipData::setClipRegion(const QRegion ®ion) } if (m_spans) { - delete m_spans; + free(m_spans); m_spans = 0; } -- cgit v0.12 From a5a842b3aa3e4033a116275c04b17d37d5595cc5 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 15 May 2009 16:45:47 +0200 Subject: doc: Update signature of eventTest() in documentation eventTest() is now non-const. --- src/corelib/statemachine/qabstracttransition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp index a930581..68423cb 100644 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -321,7 +321,7 @@ QList QAbstractTransition::animations() const #endif /*! - \fn QAbstractTransition::eventTest(QEvent *event) const + \fn QAbstractTransition::eventTest(QEvent *event) This function is called to determine whether the given \a event should cause this transition to trigger. Reimplement this function and return true if the -- cgit v0.12 From c11b50366069b9c5a0daa74dc3511d91ceafe564 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 15 May 2009 17:01:37 +0200 Subject: doc: New state chart diagrams for Stickman example These obviously cannot be used, since they have the "unregistered version" watermark on them. Didn't notice before now, so I might as well commit them for the time being. --- doc/src/images/stickman-example1.png | Bin 8311 -> 33216 bytes doc/src/images/stickman-example2.png | Bin 0 -> 23521 bytes doc/src/images/stickman-example3.png | Bin 0 -> 12265 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/src/images/stickman-example2.png create mode 100644 doc/src/images/stickman-example3.png diff --git a/doc/src/images/stickman-example1.png b/doc/src/images/stickman-example1.png index 7b9a5b8..8ee364b 100644 Binary files a/doc/src/images/stickman-example1.png and b/doc/src/images/stickman-example1.png differ diff --git a/doc/src/images/stickman-example2.png b/doc/src/images/stickman-example2.png new file mode 100644 index 0000000..0e4c57d Binary files /dev/null and b/doc/src/images/stickman-example2.png differ diff --git a/doc/src/images/stickman-example3.png b/doc/src/images/stickman-example3.png new file mode 100644 index 0000000..62f41eb Binary files /dev/null and b/doc/src/images/stickman-example3.png differ -- cgit v0.12 From ad17d5fcaa5984e7f11e3c8a514a24264890c827 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 18 May 2009 14:06:31 +0200 Subject: Fixed access to members of an object. Reviewed-by: David Boddie --- doc/src/animation.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/animation.qdoc b/doc/src/animation.qdoc index f3baf71..b4e603c 100644 --- a/doc/src/animation.qdoc +++ b/doc/src/animation.qdoc @@ -271,10 +271,10 @@ \code QPushButton *bonnie = new QPushButton("Bonnie"); - bonnie.show(); + bonnie->show(); QPushButton *clyde = new QPushButton("Clyde"); - clyde.show(); + clyde->show(); QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry"); // Set up anim1 -- cgit v0.12 From 3d99537a86144b8f22ef10891ba6cc55820b987a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 18 May 2009 14:24:58 +0200 Subject: doc: Minor fixes + update UML diagrams for stick man example Using StarUML this time, since there were "unregistered version" watermarks on the Enterprise Architect ones. Not as nice, but it's impossible to find a free UML tool which produces nice diagrams. --- doc/src/examples.qdoc | 6 ++++++ doc/src/examples/stickman.qdoc | 8 ++++---- doc/src/images/stickman-example1.png | Bin 33216 -> 64543 bytes doc/src/images/stickman-example2.png | Bin 23521 -> 37412 bytes doc/src/images/stickman-example3.png | Bin 12265 -> 23591 bytes 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc index 6603390..c55d29f 100644 --- a/doc/src/examples.qdoc +++ b/doc/src/examples.qdoc @@ -86,6 +86,12 @@ \o \l{activeqt/webbrowser}{Web Browser}\raisedaster \o \l{activeqt/wrapper}{Wrapper}\raisedaster \endlist + + \section1 Animation + + \list + \o \l{animation/stickman}{Stick man}\raisedaster + \endlist \section1 Concurrent Programming diff --git a/doc/src/examples/stickman.qdoc b/doc/src/examples/stickman.qdoc index 0313c81..49f4953 100644 --- a/doc/src/examples/stickman.qdoc +++ b/doc/src/examples/stickman.qdoc @@ -56,7 +56,7 @@ represents a frame in the animation by setting the position of each joint in the stickman's skeleton to the positions defined for the particular frame. The frames are then bound together with animated transitions that trigger on the source state's polished() signal. Thus, the - machine will enter the state representing the next state in the animation immediately after it + machine will enter the state representing the next frame in the animation immediately after it has finished animating into the previous frame. \image stickman-example1.png @@ -74,7 +74,7 @@ The last frame state is given a transition to the first one, so that the animation will loop until it is interrupted when a transition out from the animation state is taken. To get smooth animations between the different key frames, we set a default animation on the state machine. - This is a parallel animation group which contain animations for all the "position" properties + This is a parallel animation group which contains animations for all the "position" properties and will be selected by default when taking any transition that leads into a state that assigns values to these properties. @@ -91,12 +91,12 @@ applying the default animation when interrupting one and starting another. Finally, there is a transition out from the "alive" state and into the "dead" state. This is - a custom transition type called LightningStrikesTransition which samples every second and + a custom transition type called LightningSrikesTransition which samples every second and triggers at random (one out of fifty times on average.) \snippet examples/animation/stickman/lifecycle.cpp 4 - When it triggers, the machine will first enter a "lightningStrike" state which uses a timer to + When it triggers, the machine will first enter a "lightningBlink" state which uses a timer to pause for a brief period of time while the background color of the scene is white. This gives us a flash effect when the lightning strikes. diff --git a/doc/src/images/stickman-example1.png b/doc/src/images/stickman-example1.png index 8ee364b..1596a68 100644 Binary files a/doc/src/images/stickman-example1.png and b/doc/src/images/stickman-example1.png differ diff --git a/doc/src/images/stickman-example2.png b/doc/src/images/stickman-example2.png index 0e4c57d..980276a 100644 Binary files a/doc/src/images/stickman-example2.png and b/doc/src/images/stickman-example2.png differ diff --git a/doc/src/images/stickman-example3.png b/doc/src/images/stickman-example3.png index 62f41eb..3635ff7 100644 Binary files a/doc/src/images/stickman-example3.png and b/doc/src/images/stickman-example3.png differ -- cgit v0.12 From 8ef2feacb26eabdc6e82c4a85b6f3e30665477ba Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Tue, 19 May 2009 13:35:24 +0200 Subject: Whitespace cleanup in QEasingCurve --- src/corelib/tools/qeasingcurve.cpp | 89 +++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index a1a0d1f..72965de5 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -99,7 +99,7 @@ \br Easing equation function for a simple linear tweening, with no easing. - \value InQuad \inlineimage qeasingcurve-inquad.png + \value InQuad \inlineimage qeasingcurve-inquad.png \br Easing equation function for a quadratic (t^2) easing in: accelerating from zero velocity. @@ -107,7 +107,7 @@ \br Easing equation function for a quadratic (t^2) easing out: decelerating to zero velocity. - \value InOutQuad \inlineimage qeasingcurve-inoutquad.png + \value InOutQuad \inlineimage qeasingcurve-inoutquad.png \br Easing equation function for a quadratic (t^2) easing in/out: acceleration until halfway, then deceleration. @@ -121,11 +121,11 @@ in: accelerating from zero velocity. \value OutCubic \inlineimage qeasingcurve-outcubic.png \br - Easing equation function for a cubic (t^3) easing + Easing equation function for a cubic (t^3) easing out: decelerating from zero velocity. \value InOutCubic \inlineimage qeasingcurve-inoutcubic.png \br - Easing equation function for a cubic (t^3) easing + Easing equation function for a cubic (t^3) easing in/out: acceleration until halfway, then deceleration. \value OutInCubic \inlineimage qeasingcurve-outincubic.png \br @@ -133,55 +133,55 @@ out/in: deceleration until halfway, then acceleration. \value InQuart \inlineimage qeasingcurve-inquart.png \br - Easing equation function for a quartic (t^4) easing + Easing equation function for a quartic (t^4) easing in: accelerating from zero velocity. \value OutQuart \inlineimage qeasingcurve-outquart.png \br - Easing equation function for a quartic (t^4) easing + Easing equation function for a quartic (t^4) easing out: decelerating from zero velocity. \value InOutQuart \inlineimage qeasingcurve-inoutquart.png \br - Easing equation function for a quartic (t^4) easing + Easing equation function for a quartic (t^4) easing in/out: acceleration until halfway, then deceleration. \value OutInQuart \inlineimage qeasingcurve-outinquart.png \br - Easing equation function for a quartic (t^4) easing + Easing equation function for a quartic (t^4) easing out/in: deceleration until halfway, then acceleration. \value InQuint \inlineimage qeasingcurve-inquint.png \br - Easing equation function for a quintic (t^5) easing + Easing equation function for a quintic (t^5) easing in: accelerating from zero velocity. \value OutQuint \inlineimage qeasingcurve-outquint.png \br - Easing equation function for a quintic (t^5) easing + Easing equation function for a quintic (t^5) easing out: decelerating from zero velocity. \value InOutQuint \inlineimage qeasingcurve-inoutquint.png \br - Easing equation function for a quintic (t^5) easing + Easing equation function for a quintic (t^5) easing in/out: acceleration until halfway, then deceleration. \value OutInQuint \inlineimage qeasingcurve-outinquint.png \br - Easing equation function for a quintic (t^5) easing + Easing equation function for a quintic (t^5) easing out/in: deceleration until halfway, then acceleration. \value InSine \inlineimage qeasingcurve-insine.png \br - Easing equation function for a sinusoidal (sin(t)) easing + Easing equation function for a sinusoidal (sin(t)) easing in: accelerating from zero velocity. \value OutSine \inlineimage qeasingcurve-outsine.png \br - Easing equation function for a sinusoidal (sin(t)) easing + Easing equation function for a sinusoidal (sin(t)) easing out: decelerating from zero velocity. \value InOutSine \inlineimage qeasingcurve-inoutsine.png \br - Easing equation function for a sinusoidal (sin(t)) easing + Easing equation function for a sinusoidal (sin(t)) easing in/out: acceleration until halfway, then deceleration. \value OutInSine \inlineimage qeasingcurve-outinsine.png \br - Easing equation function for a sinusoidal (sin(t)) easing + Easing equation function for a sinusoidal (sin(t)) easing out/in: deceleration until halfway, then acceleration. \value InExpo \inlineimage qeasingcurve-inexpo.png \br - Easing equation function for an exponential (2^t) easing + Easing equation function for an exponential (2^t) easing in: accelerating from zero velocity. \value OutExpo \inlineimage qeasingcurve-outexpo.png \br @@ -213,47 +213,47 @@ out/in: deceleration until halfway, then acceleration. \value InElastic \inlineimage qeasingcurve-inelastic.png \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing in: + Easing equation function for an elastic + (exponentially decaying sine wave) easing in: accelerating from zero velocity. The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. \value OutElastic \inlineimage qeasingcurve-outelastic.png \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing out: - decelerating from zero velocity. The peak amplitude - can be set with the \e amplitude parameter, and the + Easing equation function for an elastic + (exponentially decaying sine wave) easing out: + decelerating from zero velocity. The peak amplitude + can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. \value InOutElastic \inlineimage qeasingcurve-inoutelastic.png \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing in/out: + Easing equation function for an elastic + (exponentially decaying sine wave) easing in/out: acceleration until halfway, then deceleration. \value OutInElastic \inlineimage qeasingcurve-outinelastic.png \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing out/in: + Easing equation function for an elastic + (exponentially decaying sine wave) easing out/in: deceleration until halfway, then acceleration. \value InBack \inlineimage qeasingcurve-inback.png \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing in: + Easing equation function for a back (overshooting + cubic easing: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity. \value OutBack \inlineimage qeasingcurve-outback.png \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing out: + Easing equation function for a back (overshooting + cubic easing: (s+1)*t^3 - s*t^2) easing out: decelerating from zero velocity. \value InOutBack \inlineimage qeasingcurve-inoutback.png \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing in/out: + Easing equation function for a back (overshooting + cubic easing: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration. \value OutInBack \inlineimage qeasingcurve-outinback.png \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing out/in: + Easing equation function for a back (overshooting + cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration. \value InBounce \inlineimage qeasingcurve-inbounce.png \br @@ -283,14 +283,13 @@ \omitvalue NCurveTypes */ -/*! +/*! \typedef QEasingCurve::EasingFunction This is a typedef for a pointer to a function with the following signature: \snippet doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp 0 - */ #include "qeasingcurve.h" @@ -646,10 +645,10 @@ bool QEasingCurve::operator==(const QEasingCurve &other) const \fn bool QEasingCurve::operator!=(const QEasingCurve &other) const Compare this easing curve with \a other and returns true if they are not equal. It will also compare the properties of a curve. - + \sa operator==() */ - + /*! Returns the amplitude. This is not applicable for all curve types. It is only applicable for bounce and elastic curves (curves of type() @@ -664,8 +663,8 @@ qreal QEasingCurve::amplitude() const /*! Sets the amplitude to \a amplitude. - - This will set the amplitude of the bounce or the amplitude of the + + This will set the amplitude of the bounce or the amplitude of the elastic "spring" effect. The higher the number, the higher the amplitude. \sa amplitude() */ @@ -688,7 +687,7 @@ qreal QEasingCurve::period() const /*! Sets the period to \a period. - Setting a small period value will give a high frequency of the curve. A + Setting a small period value will give a high frequency of the curve. A large period will give it a small frequency. \sa period() @@ -745,7 +744,7 @@ void QEasingCurvePrivate::setType_helper(QEasingCurve::Type newType) delete config; config = 0; } - + if (isConfigFunction(newType) || (amp != -1.0) || (period != -1.0) || (overshoot != -1.0)) { config = curveToFunctionObject(newType); if (amp != -1.0) @@ -800,7 +799,7 @@ void QEasingCurve::setCustomType(EasingFunction func) /*! Returns the function pointer to the custom easing curve. - If type() does not return QEasingCurve::Custom, this function + If type() does not return QEasingCurve::Custom, this function will return 0. */ QEasingCurve::EasingFunction QEasingCurve::customType() const @@ -830,7 +829,7 @@ qreal QEasingCurve::valueForProgress(qreal progress) const #include QDebug operator<<(QDebug debug, const QEasingCurve &item) { - debug << "type:" << item.d_ptr->type + debug << "type:" << item.d_ptr->type << "func:" << item.d_ptr->func; if (item.d_ptr->config) { debug << QString::fromAscii("period:%1").arg(item.d_ptr->config->_p, 0, 'f', 20) -- cgit v0.12 From a903f9fb54f7192795abffca0a99b54d419bdb7a Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Tue, 19 May 2009 13:35:58 +0200 Subject: Removed memory leak in QEasingCurvePrivate Task-number: 253898 --- src/corelib/tools/qeasingcurve.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 72965de5..9ef9149 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -354,6 +354,7 @@ public: config(0), func(&easeNone) { } + ~QEasingCurvePrivate() { delete config; } void setType_helper(QEasingCurve::Type); QEasingCurve::Type type; -- cgit v0.12 From 1c64881836a7003b20e0da97b95c94394c476525 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 19 May 2009 13:41:22 +0200 Subject: Doc: Added information about ownership of animations. Reviewed-by: Thierry Bastian --- src/corelib/animation/qanimationgroup.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp index e0be3f7..e78ce9a 100644 --- a/src/corelib/animation/qanimationgroup.cpp +++ b/src/corelib/animation/qanimationgroup.cpp @@ -159,7 +159,7 @@ int QAnimationGroup::animationCount() const Returns the index of \a animation. The returned index can be passed to the other functions that take an index as an argument. - \sa insertAnimationAt() animationAt(), takeAnimationAt() + \sa insertAnimationAt(), animationAt(), takeAnimationAt() */ int QAnimationGroup::indexOfAnimation(QAbstractAnimation *animation) const { @@ -169,7 +169,11 @@ int QAnimationGroup::indexOfAnimation(QAbstractAnimation *animation) const /*! Adds \a animation to this group. This will call insertAnimationAt with - index equals to animationCount() + index equals to animationCount(). + + \note The group takes ownership of the animation. + + \sa removeAnimation() */ void QAnimationGroup::addAnimation(QAbstractAnimation *animation) { @@ -181,7 +185,10 @@ void QAnimationGroup::addAnimation(QAbstractAnimation *animation) Inserts \a animation into this animation group at \a index. If \a index is 0 the animation is inserted at the beginning. If \a index is animationCount(), the animation is inserted at the end. - \sa takeAnimationAt(), addAnimation(), indexOfAnimation() + + \note The group takes ownership of the animation. + + \sa takeAnimationAt(), addAnimation(), indexOfAnimation(), removeAnimation() */ void QAnimationGroup::insertAnimationAt(int index, QAbstractAnimation *animation) { @@ -226,11 +233,11 @@ void QAnimationGroup::removeAnimation(QAbstractAnimation *animation) } /*! - Removes the animation at \a index from this animation group. The ownership - of the animation is transferred to the caller, and a pointer to the removed - animation is returned. + Returns the animation at \a index and removes it from the animation group. + + \note The ownership of the animation is transferred to the caller. - \sa addAnimation() + \sa removeAnimation(), addAnimation(), insertAnimation(), indexOfAnimation() */ QAbstractAnimation *QAnimationGroup::takeAnimationAt(int index) { -- cgit v0.12 From 91803020462b7e42128644bdd9ed1d3455787f79 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Tue, 19 May 2009 14:17:02 +0200 Subject: Removed unused method from QVariantAnimationPrivate --- src/corelib/animation/qvariantanimation.cpp | 6 ------ src/corelib/animation/qvariantanimation_p.h | 1 - 2 files changed, 7 deletions(-) diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 157a321..8ac8ca1 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -217,12 +217,6 @@ void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/) setCurrentValueForProgress(progress); } -void QVariantAnimationPrivate::setCurrentValue() -{ - const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration))); - setCurrentValueForProgress(progress); -} - void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress) { Q_Q(QVariantAnimation); diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h index 9e81649..8b2915b 100644 --- a/src/corelib/animation/qvariantanimation_p.h +++ b/src/corelib/animation/qvariantanimation_p.h @@ -108,7 +108,6 @@ public: quint32 changedSignalMask; - void setCurrentValue(); void setCurrentValueForProgress(const qreal progress); void recalculateCurrentInterval(bool force=false); void setValueAt(qreal, const QVariant &); -- cgit v0.12 From b2302dcc101fcef3c2841e9bd47790332e1cd4c2 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Tue, 19 May 2009 17:31:47 +0200 Subject: Removing QT_EXPERIMENTAL_SOLUTION from the animation api --- examples/animation/animatedtiles/main.cpp | 11 ----------- examples/animation/appchooser/main.cpp | 3 --- examples/animation/easing/animation.h | 6 +----- examples/animation/moveblocks/main.cpp | 9 --------- examples/animation/padnavigator-ng/panel.h | 4 ---- examples/animation/padnavigator-ng/roundrectitem.h | 4 ---- examples/animation/padnavigator-ng/splashitem.h | 4 ---- .../research/memberfunctions/qvalueanimation.h | 6 +----- examples/animation/states/main.cpp | 8 -------- examples/animation/stickman/lifecycle.cpp | 9 --------- examples/animation/sub-attaq/animationmanager.cpp | 6 +----- examples/animation/sub-attaq/boat.cpp | 10 ---------- examples/animation/sub-attaq/boat.h | 6 +----- examples/animation/sub-attaq/boat_p.h | 6 +----- examples/animation/sub-attaq/bomb.cpp | 8 -------- examples/animation/sub-attaq/bomb.h | 9 ++------- .../animation/sub-attaq/custompropertyanimation.h | 6 +----- examples/animation/sub-attaq/graphicsscene.cpp | 9 --------- examples/animation/sub-attaq/graphicsscene.h | 7 +------ examples/animation/sub-attaq/qanimationstate.cpp | 9 ++------- examples/animation/sub-attaq/states.cpp | 7 ------- examples/animation/sub-attaq/states.h | 9 +-------- examples/animation/sub-attaq/submarine.cpp | 8 -------- examples/animation/sub-attaq/submarine.h | 5 ----- examples/animation/sub-attaq/submarine_p.h | 4 ---- examples/animation/sub-attaq/torpedo.cpp | 6 ------ examples/animation/sub-attaq/torpedo.h | 9 ++------- src/corelib/animation/qabstractanimation.cpp | 20 -------------------- src/corelib/animation/qabstractanimation.h | 4 ---- src/corelib/animation/qabstractanimation_p.h | 9 --------- src/corelib/animation/qanimationgroup.h | 6 +----- src/corelib/animation/qparallelanimationgroup.h | 6 +----- src/corelib/animation/qpauseanimation.h | 6 +----- src/corelib/animation/qpropertyanimation.h | 6 +----- src/corelib/animation/qsequentialanimationgroup.h | 6 +----- src/corelib/animation/qvariantanimation.cpp | 5 +---- src/corelib/animation/qvariantanimation.h | 9 ++------- src/corelib/animation/qvariantanimation_p.h | 6 +----- src/corelib/tools/qeasingcurve.cpp | 6 +----- src/gui/animation/qguivariantanimation.cpp | 5 ----- 40 files changed, 24 insertions(+), 258 deletions(-) diff --git a/examples/animation/animatedtiles/main.cpp b/examples/animation/animatedtiles/main.cpp index a97eaf3..7988758 100644 --- a/examples/animation/animatedtiles/main.cpp +++ b/examples/animation/animatedtiles/main.cpp @@ -40,18 +40,7 @@ ****************************************************************************/ #include -#ifdef QT_EXPERIMENTAL_SOLUTION -# include "qgraphicswidget.h" -# include "qstate.h" -# include "qstatemachine.h" -# include "qabstracttransition.h" -# include "qgraphicswidget.h" -# include "qparallelanimationgroup.h" -# include "qpropertyanimation.h" -# include "qsignaltransition.h" -#else #include -#endif class Pixmap : public QObject, public QGraphicsPixmapItem { diff --git a/examples/animation/appchooser/main.cpp b/examples/animation/appchooser/main.cpp index 1c63aba..44457f7 100644 --- a/examples/animation/appchooser/main.cpp +++ b/examples/animation/appchooser/main.cpp @@ -41,9 +41,6 @@ #include #include -#ifdef QT_EXPERIMENTAL_SOLUTION -#include "qtgraphicswidget.h" -#endif class Pixmap : public QGraphicsWidget diff --git a/examples/animation/easing/animation.h b/examples/animation/easing/animation.h index c9472e1..d4d699d 100644 --- a/examples/animation/easing/animation.h +++ b/examples/animation/easing/animation.h @@ -44,11 +44,7 @@ #include -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qpropertyanimation.h" -#else -# include -#endif +#include class Animation : public QPropertyAnimation { public: diff --git a/examples/animation/moveblocks/main.cpp b/examples/animation/moveblocks/main.cpp index 0ce07fc..b00485e 100644 --- a/examples/animation/moveblocks/main.cpp +++ b/examples/animation/moveblocks/main.cpp @@ -41,15 +41,6 @@ #include #include -#if defined(QT_EXPERIMENTAL_SOLUTION) -#include "qstatemachine.h" -#include "qstate.h" -#include "qabstracttransition.h" -#include "qpropertyanimation.h" -#include "qsequentialanimationgroup.h" -#include "qparallelanimationgroup.h" -#include "qgraphicswidget.h" -#endif #include class StateSwitchEvent: public QEvent diff --git a/examples/animation/padnavigator-ng/panel.h b/examples/animation/padnavigator-ng/panel.h index 35d0db5..8ad95d9 100644 --- a/examples/animation/padnavigator-ng/panel.h +++ b/examples/animation/padnavigator-ng/panel.h @@ -40,11 +40,7 @@ ****************************************************************************/ #include -#ifdef QT_EXPERIMENTAL_SOLUTION -#include "qtgraphicswidget.h" -#else #include -#endif QT_BEGIN_NAMESPACE class Ui_BackSide; diff --git a/examples/animation/padnavigator-ng/roundrectitem.h b/examples/animation/padnavigator-ng/roundrectitem.h index fb142c6..6a7bf4b 100644 --- a/examples/animation/padnavigator-ng/roundrectitem.h +++ b/examples/animation/padnavigator-ng/roundrectitem.h @@ -41,11 +41,7 @@ #include #include -#ifdef QT_EXPERIMENTAL_SOLUTION -#include "qtgraphicswidget.h" -#else #include -#endif QT_BEGIN_NAMESPACE class QGraphicsProxyWidget; diff --git a/examples/animation/padnavigator-ng/splashitem.h b/examples/animation/padnavigator-ng/splashitem.h index 05ff040..7b4b8a9 100644 --- a/examples/animation/padnavigator-ng/splashitem.h +++ b/examples/animation/padnavigator-ng/splashitem.h @@ -40,11 +40,7 @@ ****************************************************************************/ #include -#ifdef QT_EXPERIMENTAL_SOLUTION -#include "qtgraphicswidget.h" -#else #include -#endif class SplashItem : public QGraphicsWidget { diff --git a/examples/animation/research/memberfunctions/qvalueanimation.h b/examples/animation/research/memberfunctions/qvalueanimation.h index 55c4993..17e9817 100644 --- a/examples/animation/research/memberfunctions/qvalueanimation.h +++ b/examples/animation/research/memberfunctions/qvalueanimation.h @@ -42,11 +42,7 @@ #ifndef QVALUEANIMATION_H #define QVALUEANIMATION_H -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qvariantanimation.h" -#else -# include -#endif +#include QT_BEGIN_HEADER diff --git a/examples/animation/states/main.cpp b/examples/animation/states/main.cpp index 06b0667..17a7a8e 100644 --- a/examples/animation/states/main.cpp +++ b/examples/animation/states/main.cpp @@ -40,14 +40,6 @@ ****************************************************************************/ #include -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qstate.h" -# include "qstatemachine.h" -# include "qtransition.h" -# include "qparallelanimationgroup.h" -# include "qsequentialanimationgroup.h" -# include "qpropertyanimation.h" -#endif class Pixmap : public QGraphicsWidget { diff --git a/examples/animation/stickman/lifecycle.cpp b/examples/animation/stickman/lifecycle.cpp index 1feb31d..eb4ed11 100644 --- a/examples/animation/stickman/lifecycle.cpp +++ b/examples/animation/stickman/lifecycle.cpp @@ -47,15 +47,6 @@ #include #include -#if defined(QT_EXPERIMENTAL_SOLUTION) -#include "qstatemachine.h" -#include "qstate.h" -#include "qeventtransition.h" -#include "qsignaltransition.h" -#include "qsignalevent.h" -#include "qpropertyanimation.h" -#include "qparallelanimationgroup.h" -#endif class KeyPressTransition: public QSignalTransition { diff --git a/examples/animation/sub-attaq/animationmanager.cpp b/examples/animation/sub-attaq/animationmanager.cpp index 5b9282a..477d3bd 100644 --- a/examples/animation/sub-attaq/animationmanager.cpp +++ b/examples/animation/sub-attaq/animationmanager.cpp @@ -43,11 +43,7 @@ #include "animationmanager.h" //Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qabstractanimation.h" -#else -# include -#endif +#include #include // the universe's only animation manager diff --git a/examples/animation/sub-attaq/boat.cpp b/examples/animation/sub-attaq/boat.cpp index 143cf94..63d12bb 100644 --- a/examples/animation/sub-attaq/boat.cpp +++ b/examples/animation/sub-attaq/boat.cpp @@ -50,22 +50,12 @@ #include "qanimationstate.h" //Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qpropertyanimation.h" -# include "qstatemachine.h" -# include "qhistorystate.h" -# include "qfinalstate.h" -# include "qstate.h" -# include "qpauseanimation.h" -#include "qsequentialanimationgroup.h" -#else #include #include #include #include #include #include -#endif static QAbstractAnimation *setupDestroyAnimation(Boat *boat) { diff --git a/examples/animation/sub-attaq/boat.h b/examples/animation/sub-attaq/boat.h index b28cf20..f16074e 100644 --- a/examples/animation/sub-attaq/boat.h +++ b/examples/animation/sub-attaq/boat.h @@ -46,11 +46,7 @@ #include #include -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qtgraphicswidget.h" -#else -# include -#endif +#include class PixmapItem; class Bomb; diff --git a/examples/animation/sub-attaq/boat_p.h b/examples/animation/sub-attaq/boat_p.h index 6f03e48..c934bc5 100644 --- a/examples/animation/sub-attaq/boat_p.h +++ b/examples/animation/sub-attaq/boat_p.h @@ -47,11 +47,7 @@ #include "graphicsscene.h" // Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qkeyeventtransition.h" -#else -# include -#endif +#include static const int MAX_BOMB = 5; diff --git a/examples/animation/sub-attaq/bomb.cpp b/examples/animation/sub-attaq/bomb.cpp index 04310aa..f1f5324 100644 --- a/examples/animation/sub-attaq/bomb.cpp +++ b/examples/animation/sub-attaq/bomb.cpp @@ -47,18 +47,10 @@ #include "qanimationstate.h" //Qt - -#if defined(QT_EXPERIMENTAL_SOLUTION) -#include "qpropertyanimation.h" -#include "qsequentialanimationgroup.h" -#include "qstatemachine.h" -#include "qfinalstate.h" -#else #include #include #include #include -#endif Bomb::Bomb(QGraphicsItem * parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags), launchAnimation(0) diff --git a/examples/animation/sub-attaq/bomb.h b/examples/animation/sub-attaq/bomb.h index 9191e6e..226d056 100644 --- a/examples/animation/sub-attaq/bomb.h +++ b/examples/animation/sub-attaq/bomb.h @@ -43,13 +43,8 @@ #define __BOMB__H__ //Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qanimationgroup.h" -# include "qgraphicswidget.h" -#else -# include -# include -#endif +#include +#include class PixmapItem; diff --git a/examples/animation/sub-attaq/custompropertyanimation.h b/examples/animation/sub-attaq/custompropertyanimation.h index 48a50c9..1dca454 100644 --- a/examples/animation/sub-attaq/custompropertyanimation.h +++ b/examples/animation/sub-attaq/custompropertyanimation.h @@ -42,11 +42,7 @@ #ifndef CUSTOMPROPERTYANIMATION_H #define CUSTOMPROPERTYANIMATION_H -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qvariantanimation.h" -#else -# include -#endif +#include class QGraphicsItem; diff --git a/examples/animation/sub-attaq/graphicsscene.cpp b/examples/animation/sub-attaq/graphicsscene.cpp index 2a6f83c..f2d41bc 100644 --- a/examples/animation/sub-attaq/graphicsscene.cpp +++ b/examples/animation/sub-attaq/graphicsscene.cpp @@ -53,21 +53,12 @@ #include "progressitem.h" //Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -#include "qpropertyanimation.h" -#include "qsequentialanimationgroup.h" -#include "qparallelanimationgroup.h" -#include "qstatemachine.h" -#include "qfinalstate.h" -#include "qpauseanimation.h" -#else #include #include #include #include #include #include -#endif #include #include #include diff --git a/examples/animation/sub-attaq/graphicsscene.h b/examples/animation/sub-attaq/graphicsscene.h index 0840564..70c873e 100644 --- a/examples/animation/sub-attaq/graphicsscene.h +++ b/examples/animation/sub-attaq/graphicsscene.h @@ -45,12 +45,7 @@ //Qt #include #include - -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qstate.h" -#else -# include -#endif +#include class Boat; diff --git a/examples/animation/sub-attaq/qanimationstate.cpp b/examples/animation/sub-attaq/qanimationstate.cpp index 0f30ac2..26e0ef3 100644 --- a/examples/animation/sub-attaq/qanimationstate.cpp +++ b/examples/animation/sub-attaq/qanimationstate.cpp @@ -41,13 +41,8 @@ #include "qanimationstate.h" -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qstate.h" -# include "qstate_p.h" -#else -# include -# include -#endif +#include +#include QT_BEGIN_NAMESPACE diff --git a/examples/animation/sub-attaq/states.cpp b/examples/animation/sub-attaq/states.cpp index 7650b0f..adc8bd0 100644 --- a/examples/animation/sub-attaq/states.cpp +++ b/examples/animation/sub-attaq/states.cpp @@ -51,17 +51,10 @@ //Qt #include #include -#if defined(QT_EXPERIMENTAL_SOLUTION) -#include "qstatemachine.h" -#include "qkeyeventtransition.h" -#include "qsignalevent.h" -#include "qfinalstate.h" -#else #include #include #include #include -#endif PlayState::PlayState(GraphicsScene *scene, QState *parent) : QState(parent), diff --git a/examples/animation/sub-attaq/states.h b/examples/animation/sub-attaq/states.h index a1cb5ff..3203b3b 100644 --- a/examples/animation/sub-attaq/states.h +++ b/examples/animation/sub-attaq/states.h @@ -43,17 +43,10 @@ #define STATES_H //Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -#include "qstate.h" -#include "qsignaltransition.h" -#include "qpropertyanimation.h" -#include "qkeyeventtransition.h" -#else #include #include #include -# include -#endif +#include #include class GraphicsScene; diff --git a/examples/animation/sub-attaq/submarine.cpp b/examples/animation/sub-attaq/submarine.cpp index 0f03efc..d8cf1da 100644 --- a/examples/animation/sub-attaq/submarine.cpp +++ b/examples/animation/sub-attaq/submarine.cpp @@ -49,18 +49,10 @@ #include "custompropertyanimation.h" #include "qanimationstate.h" -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qpropertyanimation.h" -# include "qstatemachine.h" -# include "qfinalstate.h" -# include "qsequentialanimationgroup.h" -# include "qpauseanimation.h" -#else #include #include #include #include -#endif static QAbstractAnimation *setupDestroyAnimation(SubMarine *sub) { diff --git a/examples/animation/sub-attaq/submarine.h b/examples/animation/sub-attaq/submarine.h index 7ee587d..4001603 100644 --- a/examples/animation/sub-attaq/submarine.h +++ b/examples/animation/sub-attaq/submarine.h @@ -43,13 +43,8 @@ #define __SUBMARINE__H__ //Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -#include "qvariantanimation.h" -#include "qgraphicswidget.h" -#else #include #include -#endif class PixmapItem; diff --git a/examples/animation/sub-attaq/submarine_p.h b/examples/animation/sub-attaq/submarine_p.h index c76d991..561af4a 100644 --- a/examples/animation/sub-attaq/submarine_p.h +++ b/examples/animation/sub-attaq/submarine_p.h @@ -48,11 +48,7 @@ #include "qanimationstate.h" //Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -#include "qpropertyanimation.h" -#else #include -#endif #include //This state is describing when the boat is moving right diff --git a/examples/animation/sub-attaq/torpedo.cpp b/examples/animation/sub-attaq/torpedo.cpp index 88f1112..02a54fc 100644 --- a/examples/animation/sub-attaq/torpedo.cpp +++ b/examples/animation/sub-attaq/torpedo.cpp @@ -47,15 +47,9 @@ #include "animationmanager.h" #include "qanimationstate.h" -#if defined(QT_EXPERIMENTAL_SOLUTION) -#include "qpropertyanimation.h" -#include "qstatemachine.h" -#include "qfinalstate.h" -#else #include #include #include -#endif Torpedo::Torpedo(QGraphicsItem * parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags), currentSpeed(0), launchAnimation(0) diff --git a/examples/animation/sub-attaq/torpedo.h b/examples/animation/sub-attaq/torpedo.h index 2e44e41..4a0f457 100644 --- a/examples/animation/sub-attaq/torpedo.h +++ b/examples/animation/sub-attaq/torpedo.h @@ -45,13 +45,8 @@ //Qt #include -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qvariantanimation.h" -# include "qgraphicswidget.h" -#else -# include -# include -#endif +#include +#include class PixmapItem; diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index f5b9323..759cf18 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -352,42 +352,22 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) \sa QVariantAnimation, QAnimationGroup */ -#ifdef QT_EXPERIMENTAL_SOLUTION -QAbstractAnimation::QAbstractAnimation(QObject *parent) - : d_ptr(new QAbstractAnimationPrivate) -{ - // Allow auto-add on reparent - setParent(parent); - d_ptr->q_ptr = this; -} -#else QAbstractAnimation::QAbstractAnimation(QObject *parent) : QObject(*new QAbstractAnimationPrivate, 0) { // Allow auto-add on reparent setParent(parent); } -#endif /*! \internal */ -#ifdef QT_EXPERIMENTAL_SOLUTION -QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent) - : d_ptr(&dd) -{ - // Allow auto-add on reparent - setParent(parent); - d_ptr->q_ptr = this; -} -#else QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent) : QObject(dd, 0) { // Allow auto-add on reparent setParent(parent); } -#endif /*! Stops the animation if it's running, then destroys the diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index a7f0082..d6d50dc 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -123,10 +123,6 @@ protected: virtual void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); virtual void updateDirection(QAbstractAnimation::Direction direction); -#ifdef QT_EXPERIMENTAL_SOLUTION - QAbstractAnimationPrivate *d_ptr; -#endif - private: Q_DISABLE_COPY(QAbstractAnimation) Q_DECLARE_PRIVATE(QAbstractAnimation) diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 41983a5..e64554c 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -56,19 +56,13 @@ #include #include #include -#ifndef QT_EXPERIMENTAL_SOLUTION #include -#endif QT_BEGIN_NAMESPACE class QAnimationGroup; class QAbstractAnimation; -#ifdef QT_EXPERIMENTAL_SOLUTION -class QAbstractAnimationPrivate -#else class QAbstractAnimationPrivate : public QObjectPrivate -#endif { public: QAbstractAnimationPrivate() @@ -101,9 +95,6 @@ public: int currentLoop; QAnimationGroup *group; -#ifdef QT_EXPERIMENTAL_SOLUTION - QAbstractAnimation *q_ptr; -#endif private: Q_DECLARE_PUBLIC(QAbstractAnimation) diff --git a/src/corelib/animation/qanimationgroup.h b/src/corelib/animation/qanimationgroup.h index 7dee070..263bc38 100644 --- a/src/corelib/animation/qanimationgroup.h +++ b/src/corelib/animation/qanimationgroup.h @@ -42,11 +42,7 @@ #ifndef QANIMATIONGROUP_H #define QANIMATIONGROUP_H -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qabstractanimation.h" -#else -# include -#endif +#include QT_BEGIN_HEADER diff --git a/src/corelib/animation/qparallelanimationgroup.h b/src/corelib/animation/qparallelanimationgroup.h index 48d66a3..57a8146 100644 --- a/src/corelib/animation/qparallelanimationgroup.h +++ b/src/corelib/animation/qparallelanimationgroup.h @@ -42,11 +42,7 @@ #ifndef QPARALLELANIMATIONGROUP_H #define QPARALLELANIMATIONGROUP_H -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qanimationgroup.h" -#else -# include -#endif +#include QT_BEGIN_HEADER diff --git a/src/corelib/animation/qpauseanimation.h b/src/corelib/animation/qpauseanimation.h index 595f2d0..cb6e041 100644 --- a/src/corelib/animation/qpauseanimation.h +++ b/src/corelib/animation/qpauseanimation.h @@ -42,11 +42,7 @@ #ifndef QPAUSEANIMATION_P_H #define QPAUSEANIMATION_P_H -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qanimationgroup.h" -#else -# include -#endif +#include QT_BEGIN_HEADER diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h index b619256..dbd118c 100644 --- a/src/corelib/animation/qpropertyanimation.h +++ b/src/corelib/animation/qpropertyanimation.h @@ -42,11 +42,7 @@ #ifndef QPROPERTYANIMATION_H #define QPROPERTYANIMATION_H -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qvariantanimation.h" -#else -# include -#endif +#include QT_BEGIN_HEADER diff --git a/src/corelib/animation/qsequentialanimationgroup.h b/src/corelib/animation/qsequentialanimationgroup.h index 4c52d1b..4701a76 100644 --- a/src/corelib/animation/qsequentialanimationgroup.h +++ b/src/corelib/animation/qsequentialanimationgroup.h @@ -42,11 +42,7 @@ #ifndef QSEQUENTIALANIMATIONGROUP_H #define QSEQUENTIALANIMATIONGROUP_H -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qanimationgroup.h" -#else -# include -#endif +#include QT_BEGIN_HEADER diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 8ac8ca1..864575a 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -230,10 +230,7 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress) localProgress); qSwap(currentValue, ret); q->updateCurrentValue(currentValue); -#ifndef QT_EXPERIMENTAL_SOLUTION - if (connectedSignals & changedSignalMask) -#endif - if (currentValue != ret) { + if ((connectedSignals & changedSignalMask) && currentValue != ret) { //the value has changed emit q->valueChanged(currentValue); } diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h index 69dbbf3..5b90930 100644 --- a/src/corelib/animation/qvariantanimation.h +++ b/src/corelib/animation/qvariantanimation.h @@ -42,13 +42,8 @@ #ifndef QANIMATION_H #define QANIMATION_H -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qabstractanimation.h" -# include "qeasingcurve.h" -#else -# include -# include -#endif +#include +#include #include #include #include diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h index 8b2915b..e0b9c51 100644 --- a/src/corelib/animation/qvariantanimation_p.h +++ b/src/corelib/animation/qvariantanimation_p.h @@ -54,11 +54,7 @@ // #include "qvariantanimation.h" -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qeasingcurve.h" -#else -# include -#endif +#include #include #include diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 9ef9149..23eb2a6 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -340,11 +340,7 @@ bool QEasingCurveFunction::operator==(const QEasingCurveFunction& other) _o == other._o; } -#ifdef QT_EXPERIMENTAL_SOLUTION -# include "easing.cpp" -#else -# include "../3rdparty/easing/easing.cpp" -#endif +#include "../3rdparty/easing/easing.cpp" class QEasingCurvePrivate { diff --git a/src/gui/animation/qguivariantanimation.cpp b/src/gui/animation/qguivariantanimation.cpp index ed18caa..37ca6a1 100644 --- a/src/gui/animation/qguivariantanimation.cpp +++ b/src/gui/animation/qguivariantanimation.cpp @@ -41,13 +41,8 @@ #ifndef QT_NO_ANIMATION -#ifdef QT_EXPERIMENTAL_SOLUTION -# include "qvariantanimation.h" -# include "qvariantanimation_p.h" -#else #include #include -#endif #include -- cgit v0.12 From 6501f21efeb9fb327be60b8d069cfad5f19f9ff7 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 7 May 2009 14:50:47 +0200 Subject: No need to export QVariantAnimationPrivate --- src/corelib/animation/qvariantanimation_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h index e0b9c51..0d296db 100644 --- a/src/corelib/animation/qvariantanimation_p.h +++ b/src/corelib/animation/qvariantanimation_p.h @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE -class Q_CORE_EXPORT QVariantAnimationPrivate : public QAbstractAnimationPrivate +class QVariantAnimationPrivate : public QAbstractAnimationPrivate { Q_DECLARE_PUBLIC(QVariantAnimation) public: -- cgit v0.12 From c21803201a607dabc1d5a9345004d8f5dbc02d25 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 20 May 2009 11:42:25 +0200 Subject: Fix an issue that made appear warnings when the target of a property animation was destroyed The problem was that we were not really detecting when the target was destroyed. So we weren't able to unregister it from the global internal hash we have in QPropertyAnimation. This happens if an animation is running and the target object is destroyed. --- src/corelib/animation/qpropertyanimation.cpp | 27 +++++++++++++++++++++++++++ src/corelib/animation/qpropertyanimation.h | 1 + src/corelib/animation/qpropertyanimation_p.h | 5 +++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index 1755aa7..10fe8a2 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -146,6 +146,14 @@ void QPropertyAnimationPrivate::updateProperty(const QVariant &newValue) } } +void QPropertyAnimationPrivate::_q_targetDestroyed() +{ + Q_Q(QPropertyAnimation); + //we stop here so that this animation is removed from the global hash + q->stop(); + target = 0; +} + /*! Construct a QPropertyAnimation object. \a parent is passed to QObject's constructor. @@ -188,12 +196,25 @@ QObject *QPropertyAnimation::targetObject() const Q_D(const QPropertyAnimation); return d->target; } + void QPropertyAnimation::setTargetObject(QObject *target) { Q_D(QPropertyAnimation); if (d->target == target) return; + if (d->state != QAbstractAnimation::Stopped) { + qWarning("QPropertyAnimation::setTargetObject: you can't change the target of a running animation"); + return; + } + + //we need to get notified when the target is destroyed + if (d->target) + disconnect(d->target, SIGNAL(destroyed()), this, SLOT(_q_targetDestroyed())); + + if (target) + connect(target, SIGNAL(destroyed()), SLOT(_q_targetDestroyed())); + d->target = target; d->hasMetaProperty = 0; d->updateMetaProperty(); @@ -211,9 +232,15 @@ QByteArray QPropertyAnimation::propertyName() const Q_D(const QPropertyAnimation); return d->propertyName; } + void QPropertyAnimation::setPropertyName(const QByteArray &propertyName) { Q_D(QPropertyAnimation); + if (d->state != QAbstractAnimation::Stopped) { + qWarning("QPropertyAnimation::setPropertyName: you can't change the property name of a running animation"); + return; + } + d->propertyName = propertyName; d->hasMetaProperty = 0; d->updateMetaProperty(); diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h index dbd118c..5b06bd2 100644 --- a/src/corelib/animation/qpropertyanimation.h +++ b/src/corelib/animation/qpropertyanimation.h @@ -75,6 +75,7 @@ protected: void updateCurrentValue(const QVariant &value); void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); + Q_PRIVATE_SLOT(d_func(), void _q_targetDestroyed()); private: Q_DISABLE_COPY(QPropertyAnimation) Q_DECLARE_PRIVATE(QPropertyAnimation) diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h index 9d9dd31..b51d039 100644 --- a/src/corelib/animation/qpropertyanimation_p.h +++ b/src/corelib/animation/qpropertyanimation_p.h @@ -55,7 +55,6 @@ #include "qpropertyanimation.h" #include -#include #include "qvariantanimation_p.h" @@ -70,7 +69,9 @@ public: { } - QPointer target; + void _q_targetDestroyed(); + + QObject *target; //for the QProperty QMetaProperty property; -- cgit v0.12 From 66f78ca4352aeb93586d920ad3905394b15f3c0d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 20 May 2009 11:49:17 +0200 Subject: Remove old examples and demos for animations --- bin/snapshot | 359 ------------- examples/animation/example/example.pro | 12 - examples/animation/example/main.cpp | 53 -- examples/animation/example/mainwindow.cpp | 252 --------- examples/animation/example/mainwindow.h | 75 --- .../animation/research/memberfunctions/main.cpp | 89 ---- .../research/memberfunctions/memberfunctions.pro | 16 - .../research/memberfunctions/qvalueanimation.cpp | 101 ---- .../research/memberfunctions/qvalueanimation.h | 115 ---- .../research/memberfunctions/qvalueanimation_p.h | 77 --- examples/animation/research/photobrowser/main.cpp | 82 --- examples/animation/research/photobrowser/menu.cpp | 155 ------ examples/animation/research/photobrowser/menu.h | 80 --- .../research/photobrowser/photobrowser.pro | 17 - examples/animation/research/photobrowser/river.cpp | 591 --------------------- examples/animation/research/photobrowser/river.h | 111 ---- .../animation/research/photobrowser/riveritem.cpp | 125 ----- .../animation/research/photobrowser/riveritem.h | 66 --- examples/animation/research/piemenu/main.cpp | 56 -- examples/animation/research/piemenu/piemenu.pro | 8 - .../research/piemenu/qgraphicspiemenu.cpp | 250 --------- .../animation/research/piemenu/qgraphicspiemenu.h | 104 ---- .../research/piemenu/qgraphicspiemenu_p.h | 78 --- .../research/piemenu/qgraphicspiemenusection_p.h | 88 --- examples/animation/research/piemenu/scene.cpp | 73 --- examples/animation/research/piemenu/scene.h | 60 --- .../animation/research/propertytransform/main.cpp | 88 --- .../propertytransform/propertytransform.pro | 14 - .../propertytransform/qpropertytransform.h | 119 ----- examples/animation/research/sound/main.cpp | 104 ---- examples/animation/research/sound/media/sax.mp3 | Bin 417844 -> 0 bytes examples/animation/research/sound/sound.pro | 14 - examples/animation/research/sound/sound.qrc | 5 - 33 files changed, 3437 deletions(-) delete mode 100644 bin/snapshot delete mode 100644 examples/animation/example/example.pro delete mode 100644 examples/animation/example/main.cpp delete mode 100644 examples/animation/example/mainwindow.cpp delete mode 100644 examples/animation/example/mainwindow.h delete mode 100644 examples/animation/research/memberfunctions/main.cpp delete mode 100644 examples/animation/research/memberfunctions/memberfunctions.pro delete mode 100644 examples/animation/research/memberfunctions/qvalueanimation.cpp delete mode 100644 examples/animation/research/memberfunctions/qvalueanimation.h delete mode 100644 examples/animation/research/memberfunctions/qvalueanimation_p.h delete mode 100644 examples/animation/research/photobrowser/main.cpp delete mode 100644 examples/animation/research/photobrowser/menu.cpp delete mode 100644 examples/animation/research/photobrowser/menu.h delete mode 100644 examples/animation/research/photobrowser/photobrowser.pro delete mode 100644 examples/animation/research/photobrowser/river.cpp delete mode 100644 examples/animation/research/photobrowser/river.h delete mode 100644 examples/animation/research/photobrowser/riveritem.cpp delete mode 100644 examples/animation/research/photobrowser/riveritem.h delete mode 100644 examples/animation/research/piemenu/main.cpp delete mode 100644 examples/animation/research/piemenu/piemenu.pro delete mode 100644 examples/animation/research/piemenu/qgraphicspiemenu.cpp delete mode 100644 examples/animation/research/piemenu/qgraphicspiemenu.h delete mode 100644 examples/animation/research/piemenu/qgraphicspiemenu_p.h delete mode 100644 examples/animation/research/piemenu/qgraphicspiemenusection_p.h delete mode 100644 examples/animation/research/piemenu/scene.cpp delete mode 100644 examples/animation/research/piemenu/scene.h delete mode 100644 examples/animation/research/propertytransform/main.cpp delete mode 100644 examples/animation/research/propertytransform/propertytransform.pro delete mode 100644 examples/animation/research/propertytransform/qpropertytransform.h delete mode 100644 examples/animation/research/sound/main.cpp delete mode 100644 examples/animation/research/sound/media/sax.mp3 delete mode 100644 examples/animation/research/sound/sound.pro delete mode 100644 examples/animation/research/sound/sound.qrc diff --git a/bin/snapshot b/bin/snapshot deleted file mode 100644 index b9a64e1..0000000 --- a/bin/snapshot +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/perl -w -###################################################################### -# -# -###################################################################### - -# use packages ------------------------------------------------------- -use File::Basename; -use File::Path; -use Cwd; -use Config; -use strict; - -my $targetPath = ""; -my $qtdir = $ENV{"QTDIR"}; - -my @class_renames = ( - "QAbstractAnimation", - "QAnimationGroup", - "QParallelAnimationGroup", - "QSequentialAnimationGroup", - "QEasingCurve", - "QVariantAnimation", - "QPropertyAnimation", - "QItemAnimation", - "QPauseAnimation", - "QAbstractState", - "QAbstractStateGroup", - "QAbstractTransition", - "QActionState", - "QEventTransition", - "QFinalState", - "QHistoryState", - "QParallelStateGroup", - "QSignalEvent", - "QSignalTransition", - "QState", - "QStateAction", - "QStateInvokeMethodAction", - "QStateFinishedEvent", - "QStateFinishedTransition", - "QStateMachine", - "QTransition", - "QMouseEventTransition", - "QBasicMouseEventTransition", - "QKeyEventTransition", - "QBasicKeyEventTransition", - "QGraphicsWidget", - "QBoundEvent"); - -my @files = ( - "3rdparty/easing/easing.cpp", - "corelib/tools/qeasingcurve.h", - "corelib/tools/qeasingcurve.cpp", - "corelib/animation/animation.pri", - "corelib/animation/qabstractanimation.cpp", - "corelib/animation/qabstractanimation.h", - "corelib/animation/qabstractanimation_p.h", - "corelib/animation/qvariantanimation.cpp", - "corelib/animation/qvariantanimation.h", - "corelib/animation/qanimationgroup.cpp", - "corelib/animation/qvariantanimation_p.h", - "corelib/animation/qanimationgroup.h", - "corelib/animation/qanimationgroup_p.h", - "corelib/animation/qparallelanimationgroup.cpp", - "corelib/animation/qparallelanimationgroup.h", - "corelib/animation/qparallelanimationgroup_p.h", - "corelib/animation/qpauseanimation.cpp", - "corelib/animation/qpauseanimation.h", - "corelib/animation/qpropertyanimation.cpp", - "corelib/animation/qpropertyanimation.h", - "corelib/animation/qpropertyanimation_p.h", - "corelib/animation/qsequentialanimationgroup.cpp", - "corelib/animation/qsequentialanimationgroup.h", - "corelib/animation/qsequentialanimationgroup_p.h", - "gui/animation/qguivariantanimation.cpp", - "gui/animation/animation.pri", - - "corelib/statemachine/statemachine.pri", - "corelib/statemachine/qabstractstate.cpp", - "corelib/statemachine/qabstractstate.h", - "corelib/statemachine/qabstractstate_p.h", - "corelib/statemachine/qabstracttransition.cpp", - "corelib/statemachine/qabstracttransition.h", - "corelib/statemachine/qabstracttransition_p.h", - "corelib/statemachine/qactionstate.h", - "corelib/statemachine/qactionstate_p.h", - "corelib/statemachine/qactionstate.cpp", - "corelib/statemachine/qboundevent_p.h", - "corelib/statemachine/qeventtransition.cpp", - "corelib/statemachine/qeventtransition.h", - "corelib/statemachine/qeventtransition_p.h", - "corelib/statemachine/qfinalstate.cpp", - "corelib/statemachine/qfinalstate.h", - "corelib/statemachine/qhistorystate.cpp", - "corelib/statemachine/qhistorystate.h", - "corelib/statemachine/qhistorystate_p.h", - "corelib/statemachine/qsignalevent.h", - "corelib/statemachine/qsignaleventgenerator_p.h", - "corelib/statemachine/qsignaltransition.cpp", - "corelib/statemachine/qsignaltransition.h", - "corelib/statemachine/qsignaltransition_p.h", - "corelib/statemachine/qstate.cpp", - "corelib/statemachine/qstate.h", - "corelib/statemachine/qstateaction.cpp", - "corelib/statemachine/qstateaction.h", - "corelib/statemachine/qstateaction_p.h", - "corelib/statemachine/qstatefinishedevent.h", - "corelib/statemachine/qstatefinishedtransition.cpp", - "corelib/statemachine/qstatefinishedtransition.h", - "corelib/statemachine/qstatemachine.cpp", - "corelib/statemachine/qstatemachine.h", - "corelib/statemachine/qstatemachine_p.h", - "corelib/statemachine/qstate_p.h", - "corelib/statemachine/qactiontransition.cpp", - "corelib/statemachine/qactiontransition.h", - "corelib/statemachine/qactiontransition_p.h", - "gui/statemachine/qkeyeventtransition.h", - "gui/statemachine/qkeyeventtransition.cpp", - "gui/statemachine/qbasickeyeventtransition.cpp", - "gui/statemachine/qbasickeyeventtransition_p.h", - "gui/statemachine/qbasicmouseeventtransition.cpp", - "gui/statemachine/qbasicmouseeventtransition_p.h", - "gui/statemachine/qguistatemachine.cpp", - "gui/statemachine/qkeyeventtransition.cpp", - "gui/statemachine/qkeyeventtransition.h", - "gui/statemachine/qmouseeventtransition.cpp", - "gui/statemachine/qmouseeventtransition.h", - "gui/statemachine/statemachine.pri", # needs special handling - ); - - -while ( @ARGV ) { - my $arg = shift @ARGV; - if ("$arg" eq "-to") { - $targetPath = shift @ARGV; - } -} - -if ($targetPath eq "") { - die("missing -to option"); -} - -my $projectXML = "$targetPath\\files.xml"; -open(OXML, "> " . $projectXML) || die "Could not open $projectXML for writing (no write permission?)"; - -print "COPYING SOURCES...\n"; -foreach my $files(@files) { - copyFile("$qtdir/src/$files","$targetPath/src", 1); -} -copyFile("$qtdir/doc/src/animation.qdoc","$targetPath/doc", 0); -copyFile("$qtdir/doc/src/statemachine.qdoc","$targetPath/doc", 0); -copyFile("$qtdir/src/3rdparty/easing/legal.qdoc","$targetPath/doc", 0); - -copyFile("$qtdir/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp","$targetPath/doc/src/snippets/code", 0); - - -my %animation_examples = ( - easing => [ "easing.pro", - "main.cpp", - "window.cpp", - "window.h", - "animation.h", - "form.ui", - "images/qt-logo.png", - "resources.qrc"], - moveblocks => [ "moveblocks.pro", - "main.cpp" ], - animatedtiles => [ "animatedtiles.pro", - "animatedtiles.qrc", - "main.cpp", - "images/*"], - "sub-attaq" => ["sub-attaq.pro", - "animationmanager.cpp", - "animationmanager.h", - "boat.cpp", - "boat_p.h", - "boat.h", - "bomb.cpp", - "bomb.h", - "custompropertyanimation.h", - "custompropertyanimation.cpp", - "graphicsscene.cpp", - "graphicsscene.h", - "main.cpp", - "mainwindow.cpp", - "mainwindow.h", - "pics/scalable/*", - "pics/big/*.png", - "pics/big/explosion/boat/*", - "pics/big/explosion/submarine/*", - "pics/small/*", - "pics/welcome/*", - "pixmapitem.cpp", - "pixmapitem.h", - "subattaq.qrc", - "submarine.cpp", - "submarine.h", - "submarine_p.h", - "states.cpp", - "states.h", - "qanimationstate.cpp", - "qanimationstate.h", - "torpedo.cpp", - "torpedo.h", - "data.xml"], - "stickman" => ["stickman.pro", - "main.cpp", - "animation.cpp", - "animation.h", - "graphicsview.cpp", - "graphicsview.h", - "lifecycle.cpp", - "lifecycle.h", - "node.cpp", - "node.h", - "stickman.cpp", - "stickman.h", - "editor/*", - "animations/chilling", - "animations/dancing", - "animations/dead", - "animations/jumping"] - ); - -my $exDir; -print "COPYING EXAMPLES...\n"; -for $exDir ( keys %animation_examples ) { - print " $exDir...\n"; - my $i = 0; - for $i ( 0 .. $#{ $animation_examples{$exDir} } ) { - my $ex_file = $animation_examples{$exDir}[$i]; - - my $copyTargetPath; - my $glob = 0; - if (index($ex_file,"/") > 0) { - my($basefile, $fullPath) = fileparse("$targetPath/examples/$exDir/$ex_file"); - if (index($basefile, "*") >= 0) { - $glob = 1; - } - mkpath "$fullPath", 0777 unless(-e "$fullPath"); - $copyTargetPath = "$fullPath"; - } else { - $copyTargetPath = "$targetPath/examples/$exDir"; - } - my $lastCh = substr($copyTargetPath, length($copyTargetPath) - 1, 1); - if ($lastCh eq "/" || $lastCh eq "\\") { - chop($copyTargetPath); - } - - if ($glob eq 1) { - my @globFiles = < $qtdir/examples/animation/$exDir/$ex_file >; - foreach my $globFile(@globFiles) { - copyFile("$globFile", "$copyTargetPath", 0); - } - } else { - copyFile("$qtdir/examples/animation/$exDir/$ex_file", "$copyTargetPath", 0); - } - } -} - -close OXML; -print("Finished!"); - - -###################################################################### -# Syntax: copyFile(gitfile, destinationPath) -# Params: gitfile, string, filename to create duplicate for -# destinationPath, string, destination name of duplicate -# autoRename, int, 0: Don't rename -# 1: The file should be renamed to have the "qt" prefix -# -# -# Purpose: Copies to the solutions area. -# Returns: -- -# Warning: Dies if script cannot get write access. -###################################################################### -sub copyFile -{ - my ($gitfile, $destinationPath, $autoRename) = @_; - # Bi-directional synchronization - open( I, "< " . $gitfile ) || die "Could not open $gitfile for reading"; - local $/; - binmode I; - my $filecontents = ; - my ($baseFileName, $path, $ext) = fileparse($gitfile, qr/\.[^.]*/); - if ($ext eq ".h" or $ext eq ".cpp" or $ext eq ".qdoc") { - # both public and private classes - foreach my $qtClass(@class_renames) { - my $solutionClass = $qtClass; - $solutionClass =~s/^Q/Qt/g; - $filecontents =~s/$qtClass/$solutionClass/g; - my $qtFilename = lc($qtClass); - my $solutionFilename = lc($solutionClass); - $filecontents =~s/(#\s*include\s+["])$qtFilename/${1}$solutionFilename/g; - } - - $filecontents =~s/Q_CORE_EXPORT/Q_ANIMATION_EXPORT/g; - $filecontents =~s/Q_GUI_EXPORT/Q_ANIMATION_EXPORT/g; - $filecontents =~s/class Q_GUI_EXPORT/class/g; - $filecontents =~s/class Q_AUTOTEST_EXPORT/class/g; - - # moc stuff - $filecontents =~s/(#\s*include\s+["])moc_q/${1}moc_qt/g; - - $filecontents =~s/\\since 4\.[0-9]//g; - $filecontents =~s/\\ingroup [a-z]+//g; - - if (substr($filecontents, 0, 10) eq "/*********") { - my $endOfComment = index($filecontents, "*/"); - $filecontents = substr($filecontents, $endOfComment + 2); - } - } - if ($ext eq ".pri" ) { - $filecontents =~s/\$\$PWD\/q/\$\$PWD\/qt/g; - $filecontents =~s/animation\/q/\$\$PWD\/qt/g; - - # oooh such a hack this is - if ($baseFileName eq "statemachine") { - if (index($gitfile, "corelib/statemachine") >= 0) { - $baseFileName = "corelib_statemachine"; - } - if (index($gitfile, "gui/statemachine") >= 0) { - $baseFileName = "gui_statemachine"; - } - } - if ($baseFileName eq "animation") { - if (index($gitfile, "corelib/animation") >= 0) { - $baseFileName = "corelib_animation"; - } - if (index($gitfile, "gui/animation") >= 0) { - $baseFileName = "gui_animation"; - } - } - - } - - if ($ext eq ".pro") { - $filecontents = "$filecontents\ninclude(../../src/qtanimationframework.pri)\n"; - } - close I; - - mkpath $destinationPath, 0777 unless(-e "$destinationPath"); - - if ($autoRename eq 1 and ($ext eq ".h" or $ext eq ".cpp" or $ext eq ".qdoc")) { - $baseFileName =~s/^q/qt/g; - } - my $targetFile = "$destinationPath/$baseFileName$ext"; - open(O, "> " . $targetFile) || die "Could not open $targetFile for writing (no write permission?)"; - local $/; - binmode O; - print O $filecontents; - close O; - - my $xmlEntry = substr($targetFile, length($targetPath) + 1); - print "$xmlEntry\n"; - print OXML "$xmlEntry\n"; -} - diff --git a/examples/animation/example/example.pro b/examples/animation/example/example.pro deleted file mode 100644 index bc79b82..0000000 --- a/examples/animation/example/example.pro +++ /dev/null @@ -1,12 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Thu Sep 25 14:03:47 2008 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -# Input -HEADERS += mainwindow.h -SOURCES += main.cpp mainwindow.cpp diff --git a/examples/animation/example/main.cpp b/examples/animation/example/main.cpp deleted file mode 100644 index 1180b4f..0000000 --- a/examples/animation/example/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "mainwindow.h" - -int main(int argc, char *argv[]) -{ - //Q_INIT_RESOURCE(example); - QApplication app(argc, argv); - MainWindow w; - w.show(); - return app.exec(); -} - diff --git a/examples/animation/example/mainwindow.cpp b/examples/animation/example/mainwindow.cpp deleted file mode 100644 index 4aff384..0000000 --- a/examples/animation/example/mainwindow.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mainwindow.h" - -MainWindow::MainWindow() : QMainWindow(0) -{ - // Text edit and button - listWidget = new QListWidget; - new QListWidgetItem("Rachel", listWidget); - new QListWidgetItem("Andreas", listWidget); - new QListWidgetItem("David", listWidget); - new QListWidgetItem("Olivier", listWidget); - new QListWidgetItem("Andy", listWidget); - new QListWidgetItem("Martial", listWidget); - new QListWidgetItem("Kazou", listWidget); - new QListWidgetItem("Fred", listWidget); - new QListWidgetItem("Ingrid", listWidget); - QGraphicsProxyWidget *listProxy = new QGraphicsProxyWidget; - listProxy->setWidget(listWidget); - - labelWidget = new QLabel; - QGraphicsProxyWidget *labelProxy = new QGraphicsProxyWidget; - labelProxy->setWidget(labelWidget); - labelWidget->setAttribute(Qt::WA_NoSystemBackground); - - label2Widget = new QLabel; - label2Widget->setAlignment(Qt::AlignCenter); - QGraphicsProxyWidget *label2Proxy = new QGraphicsProxyWidget; - label2Proxy->setWidget(label2Widget); - label2Widget->setAttribute(Qt::WA_NoSystemBackground); - - editWidget = new QLineEdit; - QGraphicsProxyWidget *editProxy = new QGraphicsProxyWidget; - editProxy->setWidget(editWidget); - editWidget->setAttribute(Qt::WA_NoSystemBackground); - - // Parent widget - QGraphicsWidget *widget = new QGraphicsWidget; - // Parent widget - QGraphicsWidget *widget2 = new QGraphicsWidget; - - QGraphicsLinearLayout *vLayout = new QGraphicsLinearLayout(Qt::Vertical, widget); - vLayout->addItem(listProxy); - vLayout->addItem(widget2); - widget->setLayout(vLayout); - - QPushButton *button = new QPushButton; - QGraphicsProxyWidget *buttonProxy = new QGraphicsProxyWidget; - buttonProxy->setWidget(button); - - QPushButton *button2 = new QPushButton; - QGraphicsProxyWidget *buttonProxy2 = new QGraphicsProxyWidget; - buttonProxy2->setWidget(button2); - - QPushButton *button3 = new QPushButton; - QGraphicsProxyWidget *buttonProxy3 = new QGraphicsProxyWidget; - buttonProxy3->setWidget(button3); - - QPushButton *button4 = new QPushButton; - QGraphicsProxyWidget *buttonProxy4 = new QGraphicsProxyWidget; - buttonProxy4->setWidget(button4); - - QGraphicsLinearLayout *hLayout = new QGraphicsLinearLayout(Qt::Horizontal, widget2); - hLayout->addItem(buttonProxy); - hLayout->addItem(buttonProxy2); - hLayout->addItem(buttonProxy3); - widget2->setLayout(hLayout); - - scene = new QGraphicsScene(0, 0, 700, 600); - scene->setBackgroundBrush(scene->palette().window()); - scene->addItem(widget); - scene->addItem(editProxy); - scene->addItem(label2Proxy); - scene->addItem(labelProxy); - scene->addItem(buttonProxy4); - - machine = new QStateMachine(); - - group = new QState(machine->rootState()); - state1 = new QState(group); - state2 = new QState(group); - state3 = new QState(group); - group->setInitialState(state1); - - machine->setInitialState(group); - - // State 1 - state1->assignProperty(button, "text", "Edit"); - state1->assignProperty(button2, "text", "Add"); - state1->assignProperty(button3, "text", "Remove"); - state1->assignProperty(button4, "text", "Accept"); - state1->addTransition(button2, SIGNAL(clicked()), state3); - state1->assignProperty(listProxy, "geometry", QRectF(0, 0, 700, 560)); - state1->assignProperty(widget, "geometry", QRectF(0, 0, 700, 600)); - state1->assignProperty(editProxy, "opacity", double(0)); - state1->assignProperty(labelProxy, "opacity", double(0)); - state1->assignProperty(label2Proxy, "opacity", double(0)); - state1->assignProperty(buttonProxy4, "opacity", double(0)); - state1->assignProperty(labelWidget, "text", "Name : "); - state1->assignProperty(label2Widget, "text", "Edit a contact"); - state1->assignProperty(label2Proxy, "geometry", QRectF(375, -50, 300, 30)); - state1->assignProperty(labelProxy, "geometry", QRectF(350, 300, 100, 30)); - state1->assignProperty(editProxy, "geometry", QRectF(750, 300, 250, 30)); - state1->assignProperty(buttonProxy4, "geometry", QRectF(500, 350, 80, 25)); - - // State 2 - state2->assignProperty(button, "text", "Close Editing"); - state2->assignProperty(listProxy, "geometry", QRectF(0, 0, 350, 560)); - state2->addTransition(button2, SIGNAL(clicked()), state3); - state2->addTransition(button4, SIGNAL(clicked()), state1); - - state2->assignProperty(editProxy, "opacity", double(1)); - state2->assignProperty(labelProxy, "opacity", double(1)); - state2->assignProperty(label2Proxy, "opacity", double(1)); - state2->assignProperty(buttonProxy4, "opacity", double(1)); - - state2->assignProperty(label2Proxy, "geometry", QRectF(375, 250, 300, 30)); - state2->assignProperty(editProxy, "geometry", QRectF(440, 300, 260, 30)); - - // State 3 - state3->assignProperty(button4, "text", "Create New"); - state3->assignProperty(listProxy, "geometry", QRectF(0, 0, 350, 560)); - state3->addTransition(button4, SIGNAL(clicked()), state1); - state3->addTransition(button, SIGNAL(clicked()), state1); - state3->assignProperty(editProxy, "opacity", double(1)); - state3->assignProperty(labelProxy, "opacity", double(1)); - state3->assignProperty(label2Proxy, "opacity", double(1)); - state3->assignProperty(buttonProxy4, "opacity", double(1)); - - state3->assignProperty(label2Proxy, "geometry", QRectF(375, 250, 300, 30)); - state3->assignProperty(editProxy, "geometry", QRectF(440, 300, 260, 30)); - - { - QAnimationGroup *animationGroup = new QParallelAnimationGroup; - QVariantAnimation *anim = new QPropertyAnimation(labelProxy, "opacity"); - animationGroup->addAnimation(anim); - anim = new QPropertyAnimation(label2Proxy, "geometry"); - animationGroup->addAnimation(anim); - anim = new QPropertyAnimation(editProxy, "geometry"); - animationGroup->addAnimation(anim); - anim = new QPropertyAnimation(listProxy, "geometry"); - animationGroup->addAnimation(anim); - - QAbstractTransition *trans = state1->addTransition(button, SIGNAL(clicked()), state2); - trans->addAnimation(animationGroup); - } - - { - QVariantAnimation *anim; - QAnimationGroup *animationGroup = new QParallelAnimationGroup; - anim = new QPropertyAnimation(label2Proxy, "geometry"); - animationGroup->addAnimation(anim); - anim = new QPropertyAnimation(editProxy, "geometry"); - animationGroup->addAnimation(anim); - anim = new QPropertyAnimation(listProxy, "geometry"); - animationGroup->addAnimation(anim); - QAbstractTransition *trans = state2->addTransition(button, SIGNAL(clicked()), state1); - trans->addAnimation(animationGroup); - } - - currentState = state1; - - view = new QGraphicsView(scene); - - setCentralWidget(view); - - QObject::connect(state3, SIGNAL(entered()), this, SLOT(onEnterState3())); - QObject::connect(state2, SIGNAL(entered()), this, SLOT(onEnterState2())); - QObject::connect(state1, SIGNAL(entered()), this, SLOT(onEnterState1())); - - connect(listWidget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(onItemClicked(QListWidgetItem*))); - connect(button3, SIGNAL(clicked()), this, SLOT(onRemoveClicked())); - - machine->start(); -} - -void MainWindow::onEnterState2() -{ - currentState = state2; - if (listWidget->currentItem()) - editWidget->setText(listWidget->currentItem()->text()); -} - -void MainWindow::onEnterState1() -{ - if (currentState == state2 && listWidget->currentItem()) - listWidget->currentItem()->setText(editWidget->text()); - if (currentState == state3 && !editWidget->text().isNull()) { - new QListWidgetItem(editWidget->text(), listWidget); - editWidget->clear(); - } - currentState = state1; -} - -void MainWindow::onEnterState3() -{ - currentState = state3; -} - -void MainWindow::onItemClicked(QListWidgetItem*) -{ - if (currentState == state2) - { - editWidget->setText(listWidget->currentItem()->text()); - editWidget->clear(); - } -} - -void MainWindow::onRemoveClicked() -{ - QListWidgetItem *listItem = listWidget->takeItem(listWidget->currentRow()); - delete listItem; -} diff --git a/examples/animation/example/mainwindow.h b/examples/animation/example/mainwindow.h deleted file mode 100644 index 163eb89..0000000 --- a/examples/animation/example/mainwindow.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __MAINWINDOW__H__ -#define __MAINWINDOW__H__ - -#include - -class MainWindow : public QMainWindow -{ -Q_OBJECT -public: - MainWindow(); - -private slots : - void onEnterState3(); - void onEnterState2(); - void onEnterState1(); - void onItemClicked(QListWidgetItem*); - void onRemoveClicked(); -private: - QListWidget *listWidget; - QLabel *labelWidget; - QLabel *label2Widget; - QLineEdit *editWidget; - QGraphicsScene *scene; - QGraphicsView *view; - QState *state1; - QState *state2; - QState *state3; - QState *currentState; - QState *group; - QStateMachine *machine; -}; - -#endif //__MAINWINDOW__H__ - diff --git a/examples/animation/research/memberfunctions/main.cpp b/examples/animation/research/memberfunctions/main.cpp deleted file mode 100644 index 2663f9c..0000000 --- a/examples/animation/research/memberfunctions/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "qvalueanimation.h" - -AbstractProperty *qGraphicsItemProperty(QGraphicsItem *item, const char *property) -{ - if (qstrcmp(property, "pos") == 0) { - return new MemberFunctionProperty(item, &QGraphicsItem::pos, &QGraphicsItem::setPos); - } - return 0; -} - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - QGraphicsScene scene; - QGraphicsView view(&scene); - - QGraphicsItem *item = new QGraphicsRectItem(QRectF(0,0, 200, 100)); - scene.addItem(item); - - QValueAnimation *posAnim = new QValueAnimation; - posAnim->setStartValue(QPointF(0,0)); - posAnim->setEndValue(QPointF(400, 0)); - posAnim->setDuration(1000); - // Alternative 1 - //posAnim->setMemberFunction(item, &QGraphicsItem::pos, &QGraphicsItem::setPos); - - // Alternative 2 - //posAnim->setProperty(qMemberFunctionProperty(item, &QGraphicsItem::pos, &QGraphicsItem::setPos)); - - // Alternative 3 - posAnim->setProperty(qGraphicsItemProperty(item, "pos")); - - // Alternative 4, (by implementing the qGraphicsItemProperty QGraphicsItem::property()) - //posAnim->setProperty(item->property("pos")); - - // can also do this, which abstracts away the whole property thing. - // i.e. this interface can also be used for QObject-properties: - //posAnim->setAnimationProperty(animationProperty); - - posAnim->start(); - - view.resize(800,600); - view.show(); - return app.exec(); -} - diff --git a/examples/animation/research/memberfunctions/memberfunctions.pro b/examples/animation/research/memberfunctions/memberfunctions.pro deleted file mode 100644 index 6b67895..0000000 --- a/examples/animation/research/memberfunctions/memberfunctions.pro +++ /dev/null @@ -1,16 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) fr 26. sep 13:21:57 2008 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -# Input -SOURCES += main.cpp \ - qvalueanimation.cpp -HEADERS += qvalueanimation.h - -CONFIG += console - diff --git a/examples/animation/research/memberfunctions/qvalueanimation.cpp b/examples/animation/research/memberfunctions/qvalueanimation.cpp deleted file mode 100644 index de0b8ff..0000000 --- a/examples/animation/research/memberfunctions/qvalueanimation.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qvalueanimation.h" -#include "qvalueanimation_p.h" - -QT_BEGIN_NAMESPACE - - -void QValueAnimationPrivate::initDefaultStartValue() -{ - Q_Q(QValueAnimation); - if (animProp && !q->startValue().isValid() - && (currentTime == 0 - || (currentTime == duration && currentLoop == (loopCount - 1)))) { - setDefaultStartValue(animProp->read()); - } -} - - -QValueAnimation::QValueAnimation(QObject *parent) : QVariantAnimation(*new QValueAnimationPrivate, parent) -{ -} - -QValueAnimation::~QValueAnimation() -{ -} - -void QValueAnimation::setProperty(AbstractProperty *animProp) -{ - Q_D(QValueAnimation); - d->animProp = animProp; -} - -/*! - \reimp - */ -void QValueAnimation::updateCurrentValue(const QVariant &value) -{ - Q_D(QValueAnimation); - if (state() == QAbstractAnimation::Stopped) - return; - - d->animProp->write(value); -} - - -/*! - \reimp -*/ -void QValueAnimation::updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState) -{ - Q_D(QValueAnimation); - // Initialize start value - if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) - d->initDefaultStartValue(); -} - - - -#include "moc_qvalueanimation.cpp" - -QT_END_NAMESPACE diff --git a/examples/animation/research/memberfunctions/qvalueanimation.h b/examples/animation/research/memberfunctions/qvalueanimation.h deleted file mode 100644 index 17e9817..0000000 --- a/examples/animation/research/memberfunctions/qvalueanimation.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QVALUEANIMATION_H -#define QVALUEANIMATION_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QGraphicsItem; -class QValueAnimationPrivate; - -QT_MODULE(Gui) - -struct AbstractProperty { - virtual void write(const QVariant &value) = 0; - virtual QVariant read() const = 0; -}; - -# define CALL_MEMBER_FN(object,ptrToMember) ((object)->*(ptrToMember)) -template -class MemberFunctionProperty : public AbstractProperty { -public: - typedef void (Target::*RefWrite)(const T &); - typedef T (Target::*ValRead)(void) const; - - MemberFunctionProperty(Target *target, ValRead readFunc, RefWrite writeFunc) - : m_target(target), m_readFn(readFunc), m_writeFn(writeFunc) {} - - virtual void write(const QVariant &value) { - CALL_MEMBER_FN(m_target, m_writeFn)(qVariantValue(value)); - } - - virtual QVariant read() const { - if (m_readFn) - return qVariantFromValue(CALL_MEMBER_FN(m_target, m_readFn)()); - return QVariant(); - } - -private: - Target *m_target; - ValRead m_readFn; - RefWrite m_writeFn; -}; - - -class QValueAnimation : public QVariantAnimation -{ - Q_OBJECT - -public: - QValueAnimation(QObject *parent = 0); - ~QValueAnimation(); - - template - void setMemberFunction(Target *target, - T (Target::*readFunc)(void) const, // ### useValRead typedef - void (Target::*writeFunc)(const T &) // ### use RefWrite typedef - ) { - // ### ownership of MemberFunctionProperty - AbstractProperty *animProp = new MemberFunctionProperty(target, readFunc, writeFunc); - setProperty(animProp); - } - - void updateCurrentValue(const QVariant &value); - void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - void setProperty(AbstractProperty *animProp); - -private: - Q_DISABLE_COPY(QValueAnimation); - Q_DECLARE_PRIVATE(QValueAnimation); -}; - -#endif // QVALUEANIMATION_H diff --git a/examples/animation/research/memberfunctions/qvalueanimation_p.h b/examples/animation/research/memberfunctions/qvalueanimation_p.h deleted file mode 100644 index 55c8ce1..0000000 --- a/examples/animation/research/memberfunctions/qvalueanimation_p.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QVALUEANIMATION_P_H -#define QVALUEANIMATION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of QIODevice. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include //### - -QT_BEGIN_NAMESPACE - -class QValueAnimationPrivate : public QVariantAnimationPrivate -{ - Q_DECLARE_PUBLIC(QValueAnimation) -public: - QValueAnimationPrivate() : QVariantAnimationPrivate(), animProp(0) - { - } - - void initDefaultStartValue(); - - AbstractProperty *animProp; - - //###TODO -}; - -QT_END_NAMESPACE - -#endif //QVALUEANIMATION_P_H diff --git a/examples/animation/research/photobrowser/main.cpp b/examples/animation/research/photobrowser/main.cpp deleted file mode 100644 index d5ab2a3..0000000 --- a/examples/animation/research/photobrowser/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "river.h" -#include "menu.h" - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - if (app.arguments().size() == 1) { - qWarning("you have to specifiy a path to look for the photos"); - return 0; - } - - - QGraphicsScene scene; - scene.setSceneRect(QRectF(QPointF(), River::fixedSize())); - - QGraphicsView view(&scene); - view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - const int fw = view.frameWidth() * 2; - view.setFixedSize(River::fixedSize() + QSize(fw,fw)); - - River river(app.arguments()[1]); - scene.addItem(&river); - - Menu menu(&river); - menu.addAction(QLatin1String("River Mode"), &river, SLOT(setRiverMode())); - menu.addAction(QLatin1String("Grid Mode"), &river, SLOT(setGridMode())); - menu.addAction(QLatin1String("Cover Flow"), &river, SLOT(setCoverMode())); - menu.addAction(QLatin1String("Hide Menu"), &menu, SLOT(hide())); - menu.addAction(QLatin1String("Exit"), &app, SLOT(quit())); - menu.setZValue(2); - menu.setFocus(); - - river.menu = &menu; - view.show(); - - return app.exec(); -} diff --git a/examples/animation/research/photobrowser/menu.cpp b/examples/animation/research/photobrowser/menu.cpp deleted file mode 100644 index 97493ba..0000000 --- a/examples/animation/research/photobrowser/menu.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "menu.h" - -Menu::Menu(QGraphicsItem *parent) : QGraphicsWidget(parent), m_selected(0) -{ - setFlag(QGraphicsItem::ItemIsFocusable); - m_selection = new QGraphicsRectItem(this); - QLinearGradient linearGrad(QPointF(0, 0), QPointF(0,50)); - linearGrad.setColorAt(0, QColor(255,255,255,128)); - linearGrad.setColorAt(1, QColor(255,255,255,16)); - m_selection->setBrush(linearGrad); - m_selection->setPen(QPen(Qt::transparent)); -} - -Menu::~Menu() -{ -} - - -MenuAction *Menu::addAction(const QString &text, QObject *receiver, const char* slot) -{ - MenuAction *action = new MenuAction(text, this); - if (!m_actions.isEmpty()) { - MenuAction *last = m_actions.last(); - action->setPos(last->pos() + last->boundingRect().bottomLeft()); - } - m_actions.append(action); - if (m_selection->boundingRect().width() < action->boundingRect().width()) - m_selection->setRect(action->boundingRect()); - - QObject::connect(action, SIGNAL(triggered()), receiver, slot); - return action; -} - -QRectF Menu::boundingRect() const -{ - QRectF res; - foreach (MenuAction *a, m_actions) - res |= a->boundingRect(); - return res; -} - -void Menu::keyPressEvent (QKeyEvent * event) -{ - switch (event->key()) { - case Qt::Key_Escape: - hide(); - break; - case Qt::Key_Up: - m_selected -= 2; - case Qt::Key_Down: - if (!m_actions.isEmpty()) { - m_selected = (m_selected + 1 + m_actions.count()) % m_actions.count(); - QItemAnimation *anim = new QItemAnimation(m_selection, QItemAnimation::Position); - anim->setEndValue(m_actions.at(m_selected)->pos()); - anim->start(QAbstractAnimation::DeleteWhenStopped); - } - break; - case Qt::Key_Enter: - case Qt::Key_Return: - if (!m_actions.isEmpty()) { - QItemAnimation *anim = new QItemAnimation(m_selection, QItemAnimation::RotationX); - anim->setEndValue(m_selection->xRotation() < 180 ? qreal(360) : qreal(0)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - m_actions.at(m_selected)->trigger(); - hide(); - } - break; - default: - QGraphicsItem::keyPressEvent(event); - } -} - -void Menu::show() -{ - QItemAnimation *anim = new QItemAnimation(this, QItemAnimation::Opacity); - anim->setEndValue(qreal(1.)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(m_selection, QItemAnimation::ScaleFactorX); - anim->setEndValue(qreal(1)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(m_selection, QItemAnimation::ScaleFactorY); - anim->setEndValue(qreal(1)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - setFocus(); -} - -void Menu::hide() -{ - QItemAnimation *anim = new QItemAnimation(m_selection, QItemAnimation::ScaleFactorX); - anim->setEndValue(qreal(.1)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(m_selection, QItemAnimation::ScaleFactorY); - anim->setEndValue(qreal(.1)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(this, QItemAnimation::Opacity); - anim->setEndValue(qreal(0)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - parentItem()->setFocus(); -} - - -MenuAction::MenuAction(const QString &text, Menu * parent) - : QGraphicsTextItem(text,parent) -{ - QFont f = font(); - f.setPointSize(18); - setFont(f); - setDefaultTextColor(Qt::white); -} - -void MenuAction::trigger() -{ - emit triggered(); -} diff --git a/examples/animation/research/photobrowser/menu.h b/examples/animation/research/photobrowser/menu.h deleted file mode 100644 index 3bdfe45..0000000 --- a/examples/animation/research/photobrowser/menu.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __MENU__H__ -#define __MENU__H__ - -#include - -class MenuAction; - -class Menu : public QGraphicsWidget -{ - Q_OBJECT -public: - Menu(QGraphicsItem *parent); - ~Menu(); - - MenuAction *addAction(const QString&, QObject *receiver = 0, const char* slot = 0 ); - - QRectF boundingRect() const; - void keyPressEvent ( QKeyEvent * event ); -public slots: - void show(); - void hide(); -private: - QList m_actions; - QGraphicsRectItem *m_selection; - int m_selected; -}; - -class MenuAction : public QGraphicsTextItem -{ - Q_OBJECT -public: - MenuAction(const QString &text, Menu * parent); - void trigger(); -signals: - void triggered(); -}; - - -#endif //__RIVERITEM__H__ diff --git a/examples/animation/research/photobrowser/photobrowser.pro b/examples/animation/research/photobrowser/photobrowser.pro deleted file mode 100644 index 21f03d6..0000000 --- a/examples/animation/research/photobrowser/photobrowser.pro +++ /dev/null @@ -1,17 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) ven. 22. août 13:09:33 2008 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -# Input -SOURCES += main.cpp \ - river.cpp \ - riveritem.cpp \ - menu.cpp -HEADERS += river.h \ - riveritem.h \ - menu.h diff --git a/examples/animation/research/photobrowser/river.cpp b/examples/animation/research/photobrowser/river.cpp deleted file mode 100644 index 6760066..0000000 --- a/examples/animation/research/photobrowser/river.cpp +++ /dev/null @@ -1,591 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "river.h" -#include "riveritem.h" - -#include "qvariantanimation.h" - -#include -#include -#include -#include - - -#define GRID_ROW_COUNT 3 -#define GRID_COLUMN_COUNT 2 -#define GRID_DIMENSIONS (GRID_ROW_COUNT * GRID_COLUMN_COUNT) -#define ITEM_COUNT 12 - -#define RIVER_MAGNIFY(ITEM) (qreal(0.50) + (ITEM)->zValue()*2 ) -#define GRID_MAGNIFY qreal(1.5) -#define GRID_CURRENT_MAGNIFY 2 - -River::River(const QString &path) : -m_images(QDir(path).entryInfoList(QStringList() << QLatin1String("*.jpg") << QLatin1String("*.png"))), -m_currentImage(0), m_mode(RiverMode), m_selectedItem(-1) , m_topLeftIndex(-1) -{ - setFocusPolicy(Qt::StrongFocus); - setGeometry(QRectF( QPointF(), fixedSize())); - - - for (int i = 0; i < ITEM_COUNT; ++i) { - RiverItem * item = new RiverItem(this); - - //here we also randomize the x position (not when looping) - const int x = qrand() % fixedSize().width(); - item->setPos(x, -1); - - m_items.insert(m_currentImage, item); - addUnusedRiverItem(item); - } - -} - -QPointF River::gridItemPosition(int row, int col) const -{ - if (col < 0) { - col += GRID_COLUMN_COUNT; - row --; - } - return QPointF(rect().width()*(col*2 + 1)/(GRID_COLUMN_COUNT*2), - rect().height()*(row*2 + 1)/(GRID_ROW_COUNT*2)); -} - -QPixmap River::pixmap(int index) const -{ - if (index < 0 || index >= m_images.size()) - return QPixmap(); - - if (m_pixmaps.size() <= index) { - m_pixmaps.resize(index+1); - } - - if (m_pixmaps.at(index).isNull()) { - m_pixmaps[index] = QPixmap(m_images.at(index).absoluteFilePath()); - } - - return m_pixmaps.at(index); -} - -void River::addUnusedRiverItem(RiverItem * item) -{ - if (m_images.isEmpty()) - return; - - QRectF realItemRect = item->mapToParent(item->boundingRect()).boundingRect(); - - int y = item->pos().y(); - int x = item->pos().x(); - if (x >= fixedSize().width() || x < -realItemRect.width() || y < 0) { - //we set the new pixmap - - m_items.remove(m_items.key(item)); - - while (m_items.contains(m_currentImage)) - m_currentImage = (m_currentImage + 1 ) % m_images.size(); - - item->setPixmap(pixmap(m_currentImage)); - - m_items.insert(m_currentImage, item); - //this manages looping as well - m_currentImage = (m_currentImage + 1 ) % m_images.size(); - - item->setZValue(qreal(qrand()%100)/200.0); - - QItemAnimation *anim = new QItemAnimation(item, QItemAnimation::ScaleFactorX, scene()); - anim->setEndValue(RIVER_MAGNIFY(item)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorY, scene()); - anim->setEndValue(RIVER_MAGNIFY(item)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - - realItemRect = item->mapToParent(item->boundingRect()).boundingRect(); - - y = -realItemRect.y() + qrand() % (fixedSize().height() - int(realItemRect.height())); - if (x >= fixedSize().width()) { - x = -realItemRect.width()/2; - } - } - - item->setPos(x, y); - - const QPointF target(QPointF(fixedSize().width() + realItemRect.width()/2, y)); - - const int distance = target.x() - x; - - const int duration = (40 - 50*item->zValue() ) * distance; - QItemAnimation *a = new QItemAnimation(item, QItemAnimation::Position, scene()); - a->setEndValue(target); - a->setDuration(duration); - a->start(QAbstractAnimation::DeleteWhenStopped); - connect(a, SIGNAL(finished()), SLOT(animationFinished())); -} - -void River::animationFinished() -{ - QItemAnimation *anim = qobject_cast(sender()); - if (!anim || anim->propertyName() != QItemAnimation::Position) - return; - - /*RiverItem *item = static_cast(anim->graphicsItem()); - if (m_mode != RiverMode) {*/ - /*int key = m_items.key(item); - if (key < m_topLeftIndex || key >= m_topLeftIndex + GRID_DIMENSIONS) { - delete item; - m_items.remove(key); - }*/ - //return; - - //} - - addUnusedRiverItem(static_cast(anim->targetItem())); -} - -void River::switchPaused() -{ - const bool paused = m_pausedAnimations.isEmpty(); - if (paused) - m_pausedAnimations = scene()->findChildren(); - - foreach(QItemAnimation *anim, m_pausedAnimations) { - if (paused) - anim->pause(); - else - anim->resume(); - } - - if (!paused) - m_pausedAnimations.clear(); -} - -void River::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) -{ - painter->fillRect(option->rect, Qt::black); -} - -void River::setMode(Mode m) -{ - if (m_mode == m) - return; - - Mode oldMode = m_mode; - m_mode = m; - switch(m) - { - case RiverMode: - m_mode = oldMode; //some animation may be stopt, and we don't want that animationFinished we were in that mode yet - foreach (RiverItem *item, m_items) { - const int x = qrand() % fixedSize().width(); - const int y = qrand() % fixedSize().width(); - QItemAnimation *anim = new QItemAnimation(item, QItemAnimation::ScaleFactorX, scene()); - anim->setEndValue(RIVER_MAGNIFY(item)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorY, scene()); - anim->setEndValue(RIVER_MAGNIFY(item)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(item, QItemAnimation::Position, scene()); - anim->setEndValue(QPointF(x, y)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - connect(anim, SIGNAL(finished()), SLOT(animationFinished())); - } - m_mode = m; - break; - - case GridMode: - - if (oldMode == GridFullScreenMode) { - currentItem()->setFullScreen(false, GRID_CURRENT_MAGNIFY); - } else { - m_topLeftIndex = -GRID_DIMENSIONS; - foreach (RiverItem *item, m_items) { - QItemAnimation *anim = new QItemAnimation(item, QItemAnimation::ScaleFactorX, scene()); - anim->setEndValue(GRID_MAGNIFY); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorY, scene()); - anim->setEndValue(GRID_MAGNIFY); - anim->start(QAbstractAnimation::DeleteWhenStopped); - } - adjustGrid(m_currentImage - GRID_DIMENSIONS + 1); - setCurrentItem(m_topLeftIndex); - } - break; - case GridFullScreenMode: - //let's put the current item fullscreen - currentItem()->setFullScreen(true, GRID_CURRENT_MAGNIFY); - break; - case CoverMode: - m_gridItem = m_items.values(); - setCurrentItem(m_gridItem.count()/2); - default: - break; - } -} - -River::Mode River::mode() const -{ - return m_mode; -} - -QSize River::fixedSize() -{ - return QSize(352, 416); -} - -//the name of this method is not that good... -void River::makeCenterAvailable(qreal size) -{ - QRectF center(QPointF(), QSizeF(size, size)); - center.moveCenter(rect().center()); - - const QList list = scene()->items(center); - - foreach(QGraphicsItem *item, m_items) { - - if (!list.contains(item)) - continue; - - QPointF pos = item->pos(); - - if (pos.y() < rect().center().y()) { - //item is above center - pos.ry() = center.top() - item->boundingRect().height() - 1; - } else { - //item is below the center - pos.ry() = center.bottom() + 1; - } - QItemAnimation *anim = new QItemAnimation(item, QItemAnimation::Position, scene()); - anim->setEndValue(pos); - anim->setDuration(150); - anim->start(QAbstractAnimation::DeleteWhenStopped); - } -} - - -//this is there just to test small interaction -void River::keyPressEvent ( QKeyEvent * keyEvent ) -{ - switch(keyEvent->key()) - { - case Qt::Key_O: - { - QItemAnimation *anim = new QItemAnimation(this, QItemAnimation::Opacity, scene()); - anim->setDuration(2000); - anim->setEndValue(qreal(.5)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - } - break; - case Qt::Key_N: - //that's a test - makeCenterAvailable(60); - break; - case Qt::Key_P: - switchPaused(); - break; - case Qt::Key_V: - setMode(GridMode); - break; - case Qt::Key_R: - setMode(RiverMode); - break; - case Qt::Key_C: - setMode(CoverMode); - break; - case Qt::Key_Return: - case Qt::Key_Enter: - if (m_mode == RiverMode) { - setMode(GridMode); - } else if (m_mode == GridMode) { - setMode(GridFullScreenMode); - } else if (m_mode == GridFullScreenMode) { - setMode(GridMode); - } - break; - case Qt::Key_Escape: - if (m_mode == GridFullScreenMode) { - setMode(GridMode); - } else if (m_mode == GridMode || m_mode == CoverMode) { - setMode(RiverMode); - } else if (m_mode == RiverMode) { - menu->show(); - } - break; - case Qt::Key_Right: - if (m_mode == GridMode) { - navigateBy(+1); - } else if (m_mode == CoverMode) { - setCurrentItem(m_selectedItem + 1); - } - break; - case Qt::Key_Left: - if (m_mode == GridMode) { - navigateBy(-1); - } else if (m_mode == CoverMode) { - setCurrentItem(m_selectedItem - 1); - } - break; - case Qt::Key_Down: - if (m_mode == GridMode) { - navigateBy(GRID_COLUMN_COUNT); - } - break; - case Qt::Key_Up: - if (m_mode == GridMode) { - navigateBy(-GRID_COLUMN_COUNT); - } - break; -// case Qt::Key_PageUp: - case Qt::Key_M: - menu->show(); - break; - case Qt::Key_Space: - if (m_mode == GridMode) { - RiverItem *item = currentItem(); - if(!item) - break; - - //stupid sequence. - QPointF pos = item->pos(); - QAnimationGroup *group = new QSequentialAnimationGroup(); - //item->animator()->beginSequence(); - - QItemAnimation *anim = new QItemAnimation(item, QItemAnimation::Position, scene()); - anim->setEndValue(pos); - group->addAnimation(anim); - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorX, scene()); - anim->setEndValue(qreal(1.)); - anim->setDuration(500); - group->addAnimation(anim); - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorY, scene()); - anim->setEndValue(qreal(1.)); - anim->setDuration(500); - group->addAnimation(anim); - anim = new QItemAnimation(item, QItemAnimation::RotationX, scene()); - anim->setEndValue(qreal(0)); - group->addAnimation(anim); - group->start(QAbstractAnimation::DeleteWhenStopped); - } - default: - break; - } - - QGraphicsItem::keyPressEvent(keyEvent); -} - - -void River::setGridMode() -{ - setMode(GridMode); -} - -void River::setRiverMode() -{ - setMode(RiverMode); -} - -void River::setCoverMode() -{ - setMode(CoverMode); -} - - -void River::adjustGrid(int newTopLeft) -{ - for (int i = newTopLeft ; i < newTopLeft + GRID_DIMENSIONS; i++) { - if (!m_items.contains(i)) { - RiverItem *item = createItem(i); - int row = (i - m_topLeftIndex) / GRID_COLUMN_COUNT; - int col = (i - m_topLeftIndex) % GRID_COLUMN_COUNT; - item->setPos(gridItemPosition(row, col)); - item->setXScale(0); - item->setYScale(0); - QItemAnimation *anim = new QItemAnimation(item, QItemAnimation::ScaleFactorX, scene()); - anim->setEndValue(GRID_MAGNIFY); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorY, scene()); - anim->setEndValue(GRID_MAGNIFY); - anim->start(QAbstractAnimation::DeleteWhenStopped); - } - } - newTopLeft = newTopLeft - newTopLeft % GRID_COLUMN_COUNT; - - QHash::iterator it = m_items.begin(); - while (it != m_items.constEnd()) { - const int imageIdx = it.key(); - RiverItem *item = *it; - QSizeF itemSize = item->boundingRect().size(); - if ((imageIdx >= newTopLeft && imageIdx < newTopLeft + GRID_DIMENSIONS) - || boundingRect().adjusted(-itemSize.width()/2, -itemSize.height()/2, itemSize.width()/2, itemSize.height()/2) - .contains(item->pos())) { - int row = (imageIdx-newTopLeft) / GRID_COLUMN_COUNT; - int col = (imageIdx-newTopLeft) % GRID_COLUMN_COUNT; - QItemAnimation *anim = new QItemAnimation(item, QItemAnimation::Position, scene()); - anim->setEndValue(gridItemPosition(row, col)); - anim->start(QAbstractAnimation::DeleteWhenStopped); - ++it; - } else { - ++it; /* ### ideally we should remove the items, but this cause the photobrowser to crash - because the QItemAnimations are not notified the item is deleted - delete item; - it = m_items.erase(it); - */ - } - } - - m_topLeftIndex = newTopLeft; -} - - -RiverItem *River::createItem(int imageIndex) -{ - Q_ASSERT(!m_items.contains(imageIndex)); - RiverItem * item = new RiverItem(this); - item->setPixmap(pixmap(imageIndex)); - m_items.insert(imageIndex,item); - return item; -} - -void River::setCurrentItem(int newCurrentItem) -{ - if (m_mode == CoverMode) - { - m_selectedItem = newCurrentItem; - for (int i = 0; i < m_gridItem.count(); i++) { - QVariantAnimation *anim; - RiverItem *item = m_gridItem.at(i); - - qreal rotation = 0; - qreal width = boundingRect().width() / 2; - qreal x = width; - qreal scale = 3; - qreal z = 1; - qreal y = boundingRect().height()/2; - - if (i < newCurrentItem - 4) { - item->setVisible(false); - item->setPos(QPointF(0, y)); - continue; - } else if(i > newCurrentItem + 4) { - item->setVisible(false); - item->setPos(QPointF(boundingRect().width(), y)); - continue; - } else if (i < newCurrentItem) { - x = (i - newCurrentItem + 4) * width/7; - rotation = -75; - scale = 2; - z = 1.+qreal(i-newCurrentItem)/10.; - } else if (i > newCurrentItem) { - x = width + (i - newCurrentItem + 3) * width/7; - rotation = 75; - scale = 2; - z = 1.-qreal(i-newCurrentItem)/8.; - } - - item->setVisible(true); - item->setZValue(z); - - anim = new QItemAnimation(item, QItemAnimation::RotationY, scene()); - anim->setEndValue(rotation); - anim->start(QAbstractAnimation::DeleteWhenStopped); - - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorX, scene()); - anim->setEndValue(scale); - anim->start(QVariantAnimation::DeleteWhenStopped); - - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorY, scene()); - anim->setEndValue(scale); - anim->start(QVariantAnimation::DeleteWhenStopped); - - anim = new QItemAnimation(item, QItemAnimation::Position, scene()); - anim->setEndValue(QPointF(x,y)); - anim->start(QVariantAnimation::DeleteWhenStopped); - } - return; - } - - - //deselect the current item - if (m_selectedItem >= 0 && m_items.contains(m_selectedItem)) { - RiverItem *item = m_items.value(m_selectedItem); - item->setZValue(qreal(qrand()%100)/200.0); - QItemAnimation *anim = new QItemAnimation(item, QItemAnimation::ScaleFactorX, scene()); - anim->setEndValue(GRID_MAGNIFY); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorY, scene()); - anim->setEndValue(GRID_MAGNIFY); - anim->start(QAbstractAnimation::DeleteWhenStopped); - } - - if (newCurrentItem < 0) { - m_selectedItem = newCurrentItem; - return; - } - - //ensure visible; - if (newCurrentItem < m_topLeftIndex) { - adjustGrid(newCurrentItem); - } else if (newCurrentItem >= m_topLeftIndex + GRID_DIMENSIONS) { - adjustGrid(newCurrentItem - GRID_DIMENSIONS + GRID_COLUMN_COUNT); - } - - //select the new one - m_selectedItem = newCurrentItem; - RiverItem *item = currentItem(); - Q_ASSERT(item); - item->setZValue(1); - - QItemAnimation *anim = new QItemAnimation(item, QItemAnimation::ScaleFactorX, scene()); - anim->setEndValue(GRID_CURRENT_MAGNIFY); - anim->start(QAbstractAnimation::DeleteWhenStopped); - anim = new QItemAnimation(item, QItemAnimation::ScaleFactorY, scene()); - anim->setEndValue(GRID_CURRENT_MAGNIFY); - anim->start(QAbstractAnimation::DeleteWhenStopped); -} - -void River::navigateBy(int offset) -{ - int newSelection = m_selectedItem + offset; - const int imageCount = m_images.size(); - while (newSelection < 0) - newSelection += imageCount; - newSelection %= imageCount; - setCurrentItem(newSelection); -} diff --git a/examples/animation/research/photobrowser/river.h b/examples/animation/research/photobrowser/river.h deleted file mode 100644 index d6bfc76..0000000 --- a/examples/animation/research/photobrowser/river.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __RIVER__H__ -#define __RIVER__H__ - -#include -#include - -#include "menu.h" - -class RiverItem; - -class River : public QGraphicsWidget -{ - Q_OBJECT -public: - enum Mode - { - RiverMode, - GridMode, - GridFullScreenMode, - CoverMode - }; - - River(const QString &path); - void addUnusedRiverItem(RiverItem * item); - - static QSize fixedSize(); - - void switchPaused(); - - void setMode(Mode m); - Mode mode() const; - - Menu *menu; - -protected: - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - void keyPressEvent ( QKeyEvent * keyEvent ); - void makeCenterAvailable(qreal size); - QPointF gridItemPosition(int row, int col) const; - QPixmap pixmap(int index) const; - -protected slots: - void animationFinished(); -public slots: - void setRiverMode(); - void setGridMode(); - void setCoverMode(); - -private: - const QFileInfoList m_images; - int m_currentImage; - mutable QVector m_pixmaps; - QHash m_items; - QList m_gridItem; - QList m_pausedAnimations; - Mode m_mode; - - void adjustGrid(int topRight); - RiverItem *currentItem() { return m_items.value(m_selectedItem); } - RiverItem *createItem(int imageIndex); - void setCurrentItem(int currentItem); - void navigateBy(int offset); - - int m_selectedItem; - int m_topLeftIndex; - -}; - - -#endif //__RIVERITEM__H__ diff --git a/examples/animation/research/photobrowser/riveritem.cpp b/examples/animation/research/photobrowser/riveritem.cpp deleted file mode 100644 index 9692d30..0000000 --- a/examples/animation/research/photobrowser/riveritem.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "riveritem.h" -#include "river.h" - -RiverItem::RiverItem(QGraphicsItem *parent) : QGraphicsPixmapItem(parent), m_fullscreen(false) -{ - setCacheMode(DeviceCoordinateCache); -} - -RiverItem::~RiverItem() -{ -} - -void RiverItem::setPixmap(const QPixmap &pix) -{ - const QSize oldSize = pixmap().size(); - const QSize newSize = pix.size(); - QGraphicsPixmapItem::setPixmap(pix); - - if (newSize != oldSize) { - setOffset(-newSize.width()/2, -newSize.height()/2); - const qreal scaleFactor = qreal(River::fixedSize().height())/(qreal(pix.height()*7)); - setTransform(QTransform().scale(scaleFactor, scaleFactor)); - prepareGeometryChange(); - } -} - - -void RiverItem::setFullScreen(bool b, qreal originScaleFactor) -{ - if (m_fullscreen == b) - return; - - m_fullscreen = b; - - QPointF newPos; - qreal rotationZ; - qreal scaleX, scaleY; - - if (b) { - const QSizeF basePixmapSize = transform().map(boundingRect()).boundingRect().size(); - - newPos = parentItem()->boundingRect().center(); - rotationZ = 90; - scaleY = qreal(River::fixedSize().width()) / basePixmapSize.height() * yScale(); - scaleX = qreal(River::fixedSize().height()) / basePixmapSize.width() * xScale(); - - if (m_nonFSPos.isNull()) { - m_nonFSPos = pos(); //let's save our current (non fullscreen) position - } - - } else { - Q_ASSERT(!m_nonFSPos.isNull()); - rotationZ = 0; - scaleX = originScaleFactor; - scaleY = originScaleFactor; - newPos = m_nonFSPos; - } - - QAnimationGroup *group = new QParallelAnimationGroup(scene()); - QItemAnimation *anim = new QItemAnimation(this, QItemAnimation::Position); - anim->setEndValue(newPos); - group->addAnimation(anim); - anim = new QItemAnimation(this, QItemAnimation::RotationZ); - anim->setEndValue(rotationZ); - group->addAnimation(anim); - anim = new QItemAnimation(this, QItemAnimation::ScaleFactorX); - anim->setEndValue(scaleX); - group->addAnimation(anim); - anim = new QItemAnimation(this, QItemAnimation::ScaleFactorY); - anim->setEndValue(scaleY); - group->addAnimation(anim); - group->start(QAbstractAnimation::DeleteWhenStopped); -} - -void RiverItem::mousePressEvent(QGraphicsSceneMouseEvent*) -{ - //just let it rotate on itself - QItemAnimation *anim = new QItemAnimation(this, QItemAnimation::RotationY); - anim->setEndValue(yRotation() < 180 ? 360 : 0); - anim->setDuration(500); - anim->start(QAbstractAnimation::DeleteWhenStopped); -} - - diff --git a/examples/animation/research/photobrowser/riveritem.h b/examples/animation/research/photobrowser/riveritem.h deleted file mode 100644 index 2023c44..0000000 --- a/examples/animation/research/photobrowser/riveritem.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __RIVERITEM__H__ -#define __RIVERITEM__H__ - -#include - -class RiverItemAnimator; - -class RiverItem : public QGraphicsPixmapItem -{ -public: - RiverItem(QGraphicsItem *parent); - ~RiverItem(); - - void setPixmap(const QPixmap &); - void setFullScreen(bool b, qreal originScaleFactor); - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent*); - -private: - QPointF m_nonFSPos; //to save the position when not in fullscreen - bool m_fullscreen; -}; - -#endif //__RIVERITEM__H__ diff --git a/examples/animation/research/piemenu/main.cpp b/examples/animation/research/piemenu/main.cpp deleted file mode 100644 index 8076da8..0000000 --- a/examples/animation/research/piemenu/main.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "scene.h" -#include "qgraphicspiemenu.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - Scene scene; - - QGraphicsView view(&scene); - view.show(); - - return app.exec(); -} diff --git a/examples/animation/research/piemenu/piemenu.pro b/examples/animation/research/piemenu/piemenu.pro deleted file mode 100644 index 4d7a067..0000000 --- a/examples/animation/research/piemenu/piemenu.pro +++ /dev/null @@ -1,8 +0,0 @@ -SOURCES += \ - main.cpp \ - qgraphicspiemenu.cpp \ - scene.cpp -HEADERS += \ - qgraphicspiemenu.h \ - qgraphicspiemenu_p.h \ - scene.h diff --git a/examples/animation/research/piemenu/qgraphicspiemenu.cpp b/examples/animation/research/piemenu/qgraphicspiemenu.cpp deleted file mode 100644 index a199119..0000000 --- a/examples/animation/research/piemenu/qgraphicspiemenu.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgraphicspiemenu.h" -#include "qgraphicspiemenu_p.h" - -#include - -QGraphicsPieMenu::QGraphicsPieMenu(QGraphicsItem *parent) - : QGraphicsWidget(parent), d_ptr(new QGraphicsPieMenuPrivate) -{ - d_ptr->q_ptr = this; - d_ptr->machine = new QStateMachine(); - d_ptr->popupState = new QState(d_ptr->machine->rootState()); - d_ptr->machine->setInitialState(d_ptr->popupState); - d_ptr->menuAction = new QAction(this); -} - -QGraphicsPieMenu::QGraphicsPieMenu(const QString &title, QGraphicsItem *parent) - : QGraphicsWidget(parent), d_ptr(new QGraphicsPieMenuPrivate) -{ - d_ptr->q_ptr = this; - d_ptr->machine = new QStateMachine(); - d_ptr->popupState = new QState(d_ptr->machine->rootState()); - d_ptr->machine->setInitialState(d_ptr->popupState); - d_ptr->menuAction = new QAction(this); - setTitle(title); -} - -QGraphicsPieMenu::QGraphicsPieMenu(const QIcon &icon, const QString &title, QGraphicsItem *parent) - : QGraphicsWidget(parent), d_ptr(new QGraphicsPieMenuPrivate) -{ - d_ptr->q_ptr = this; - d_ptr->machine = new QStateMachine(); - d_ptr->popupState = new QState(d_ptr->machine->rootState()); - d_ptr->machine->setInitialState(d_ptr->popupState); - d_ptr->menuAction = new QAction(this); - setIcon(icon); - setTitle(title); -} - -QGraphicsPieMenu::~QGraphicsPieMenu() -{ - delete d_ptr; -} - -QAction *QGraphicsPieMenu::addAction(const QString &text) -{ - QAction *action = new QAction(text, this); - addAction(action); - return action; -} - -QAction *QGraphicsPieMenu::addAction(const QIcon &icon, const QString &text) -{ - QAction *action = new QAction(icon, text, this); - addAction(action); - return action; -} - -QAction *QGraphicsPieMenu::addAction(const QString &text, const QObject *receiver, const char *member, const QKeySequence &shortcut) -{ - QAction *action = new QAction(text, this); - action->setShortcut(shortcut); - connect(action, SIGNAL(triggered(bool)), receiver, member); - addAction(action); - return action; -} - -QAction *QGraphicsPieMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char *member, const QKeySequence &shortcut) -{ - QAction *action = new QAction(icon, text, this); - action->setShortcut(shortcut); - connect(action, SIGNAL(triggered(bool)), receiver, member); - addAction(action); - return action; -} - -QAction *QGraphicsPieMenu::addMenu(QGraphicsPieMenu *menu) -{ - QAction *action = menu->menuAction(); - addAction(action); - return action; -} - -QGraphicsPieMenu *QGraphicsPieMenu::addMenu(const QString &title) -{ - QGraphicsPieMenu *menu = new QGraphicsPieMenu(title, this); - addMenu(menu); - return menu; -} - -QGraphicsPieMenu *QGraphicsPieMenu::addMenu(const QIcon &icon, const QString &title) -{ - QGraphicsPieMenu *menu = new QGraphicsPieMenu(icon, title, this); - addMenu(menu); - return menu; -} - -QAction *QGraphicsPieMenu::addSeparator() -{ - QAction *action = new QAction(this); - action->setSeparator(true); - addAction(action); - return action; -} - -QAction *QGraphicsPieMenu::insertMenu(QAction *before, QGraphicsPieMenu *menu) -{ - QAction *action = menu->menuAction(); - insertAction(before, action); - return action; -} - -QAction *QGraphicsPieMenu::insertSeparator(QAction *before) -{ - QAction *action = new QAction(this); - action->setSeparator(true); - insertAction(before, action); - return action; -} - -QAction *QGraphicsPieMenu::menuAction() const -{ - return d_func()->menuAction; -} - -bool QGraphicsPieMenu::isEmpty() const -{ - // ### d->actions - QList actionList = actions(); - bool ret = true; - for (int i = 0; ret && i < actionList.size(); ++i) { - const QAction *action = actionList.at(i); - if (!action->isSeparator() && action->isVisible()) { - ret = false; - break; - } - } - return ret; -} - -void QGraphicsPieMenu::clear() -{ - // ### d->actions - QList actionList = actions(); - for(int i = 0; i < actionList.size(); i++) { - QAction *action = actionList.at(i); - removeAction(action); - if (action->parent() == this && action->associatedGraphicsWidgets().isEmpty()) - delete action; - } -} - -void QGraphicsPieMenu::popup(const QPointF &pos) -{ - Q_UNUSED(pos); - Q_D(QGraphicsPieMenu); - d->machine->start(); -} - -QAction *QGraphicsPieMenu::exec() -{ - return exec(pos()); -} - -QAction *QGraphicsPieMenu::exec(const QPointF &pos) -{ - Q_UNUSED(pos); - return 0; -} - -QAction *QGraphicsPieMenu::exec(QList actions, const QPointF &pos) -{ - QGraphicsPieMenu menu; - for (QList::ConstIterator it = actions.constBegin(); it != actions.constEnd(); ++it) - menu.addAction(*it); - return menu.exec(pos); -} - -QString QGraphicsPieMenu::title() const -{ - Q_D(const QGraphicsPieMenu); - return d->title; -} - -void QGraphicsPieMenu::setTitle(const QString &title) -{ - Q_D(QGraphicsPieMenu); - d->title = title; - updateGeometry(); -} - -QIcon QGraphicsPieMenu::icon() const -{ - Q_D(const QGraphicsPieMenu); - return d->icon; -} - -void QGraphicsPieMenu::setIcon(const QIcon &icon) -{ - Q_D(QGraphicsPieMenu); - d->icon = icon; - updateGeometry(); -} - -QSizeF QGraphicsPieMenu::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const -{ - Q_UNUSED(which); - Q_UNUSED(constraint); - return QSizeF(1, 1); -} diff --git a/examples/animation/research/piemenu/qgraphicspiemenu.h b/examples/animation/research/piemenu/qgraphicspiemenu.h deleted file mode 100644 index d784f93..0000000 --- a/examples/animation/research/piemenu/qgraphicspiemenu.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSPIEMENU_H -#define QGRAPHICSPIEMENU_H - -#include - -class QGraphicsPieMenuPrivate; -class QGraphicsPieMenu : public QGraphicsWidget -{ - Q_OBJECT -public: - QGraphicsPieMenu(QGraphicsItem *parent = 0); - QGraphicsPieMenu(const QString &title, QGraphicsItem *parent = 0); - QGraphicsPieMenu(const QIcon &icon, const QString &title, QGraphicsItem *parent = 0); - ~QGraphicsPieMenu(); - -#ifdef Q_NO_USING_KEYWORD - inline void addAction(QAction *action) { QGraphicsWidget::addAction(action); } -#else - using QGraphicsWidget::addAction; -#endif - QAction *addAction(const QString &text); - QAction *addAction(const QIcon &icon, const QString &text); - QAction *addAction(const QString &text, const QObject *receiver, const char *member, const QKeySequence &shortcut = 0); - QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char *member, const QKeySequence &shortcut = 0); - QAction *addMenu(QGraphicsPieMenu *menu); - QGraphicsPieMenu *addMenu(const QString &title); - QGraphicsPieMenu *addMenu(const QIcon &icon, const QString &title); - QAction *addSeparator(); - QAction *insertMenu(QAction *before, QGraphicsPieMenu *menu); - QAction *insertSeparator(QAction *before); - - QAction *menuAction() const; - - bool isEmpty() const; - void clear(); - - void popup(const QPointF &pos); - QAction *exec(); - QAction *exec(const QPointF &pos); - static QAction *exec(QList actions, const QPointF &pos); - - QString title() const; - void setTitle(const QString &title); - - QIcon icon() const; - void setIcon(const QIcon &icon); - -Q_SIGNALS: - void aboutToShow(); - void aboutToHide(); - void triggered(QAction *action); - void hovered(QAction *action); - -protected: - QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; - -private: - Q_DISABLE_COPY(QGraphicsPieMenu) - Q_DECLARE_PRIVATE(QGraphicsPieMenu) - QGraphicsPieMenuPrivate *d_ptr; -}; - -#endif diff --git a/examples/animation/research/piemenu/qgraphicspiemenu_p.h b/examples/animation/research/piemenu/qgraphicspiemenu_p.h deleted file mode 100644 index 458b8f1..0000000 --- a/examples/animation/research/piemenu/qgraphicspiemenu_p.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSPIEMENU_P_H -#define QGRAPHICSPIEMENU_P_H - -#include "qgraphicspiemenu.h" -#include "qgraphicspiemenusection_p.h" - -#include -#include -#include -#include - -class QAction; -class QEventLoop; -class QGraphicsPieMenuSection; - -class QGraphicsPieMenuPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsPieMenu); -public: - void init(const QIcon &icon = QIcon(), const QString &title = QString()); - - QIcon icon; - QString title; - QStateMachine *machine; - QState *popupState; - //QTransition *transition; - QList sections; - - QEventLoop *eventLoop; - - QAction *menuAction; - QGraphicsPieMenu *q_ptr; - - void updatePopupState(); -}; - -#endif diff --git a/examples/animation/research/piemenu/qgraphicspiemenusection_p.h b/examples/animation/research/piemenu/qgraphicspiemenusection_p.h deleted file mode 100644 index 2d71a06..0000000 --- a/examples/animation/research/piemenu/qgraphicspiemenusection_p.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSPIEMENUSECTION_H -#define QGRAPHICSPIEMENUSECTION_H - -#include -#include - -class QGraphicsPieMenuSection : public QGraphicsWidget -{ - Q_OBJECT - Q_PROPERTY(qreal rotation READ rotation WRITE setRotation) -public: - QGraphicsPieMenuSection(QGraphicsItem *parent = 0) - : QGraphicsWidget(parent), rot(0) - { } - - qreal rotation() const - { - return rot; - } - void setRotation(qreal rotation) - { - rot = rotation; - setTransform(QTransform().rotate(rot)); - } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) - { - Q_UNUSED(option); - Q_UNUSED(widget); - painter->setPen(QPen(Qt::black, 1)); - painter->setBrush(QBrush(Qt::gray)); - painter->drawPie(QRectF(-100, -100, 200, 200), 0, -30 * 16); - } - -protected: - QSizeF sizeHint(Qt::SizeHint which, const QSizeF &size = QSizeF()) const - { - Q_UNUSED(which); - Q_UNUSED(size); - return QSizeF(100, 30); - } - -private: - qreal rot; -}; - -#endif diff --git a/examples/animation/research/piemenu/scene.cpp b/examples/animation/research/piemenu/scene.cpp deleted file mode 100644 index 6309975..0000000 --- a/examples/animation/research/piemenu/scene.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgraphicspiemenu.h" -#include "scene.h" - -#include -#include - -Scene::Scene(qreal x, qreal y, qreal width, qreal height, QObject *parent) - : QGraphicsScene(x, y, width, height, parent) -{ -} - -Scene::Scene(const QRectF &sceneRect, QObject *parent) - : QGraphicsScene(sceneRect, parent) -{ -} - -Scene::Scene(QObject *parent) - : QGraphicsScene(parent) -{ -} - -Scene::~Scene() -{ -} - -void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - QGraphicsPieMenu *menu = new QGraphicsPieMenu; - for (int i = 0; i < 5; ++i) - menu->addAction(new QAction(QString("Item %1").arg(i), menu)); - menu->popup(event->scenePos()); -} diff --git a/examples/animation/research/piemenu/scene.h b/examples/animation/research/piemenu/scene.h deleted file mode 100644 index bbfe6d3..0000000 --- a/examples/animation/research/piemenu/scene.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SCENE_H -#define SCENE_H - -#include - -class Scene : public QGraphicsScene -{ - Q_OBJECT -public: - Scene(qreal x, qreal y, qreal width, qreal height, QObject *parent = 0); - Scene(const QRectF &sceneRect, QObject *parent = 0); - Scene(QObject *parent = 0); - ~Scene(); - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent *event); -}; - -#endif diff --git a/examples/animation/research/propertytransform/main.cpp b/examples/animation/research/propertytransform/main.cpp deleted file mode 100644 index 99cd769..0000000 --- a/examples/animation/research/propertytransform/main.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "qpropertytransform.h" - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - QGraphicsScene scene; - QGraphicsView view(&scene); - - QGraphicsItem *item = new QGraphicsRectItem(QRectF(0,0, 200, 100)); - scene.addItem(item); - QPropertyTransform transform; - transform.setTargetItem(item); - - QAnimationGroup *group = new QAnimationGroup(QAnimationGroup::Parallel, &scene); - QPropertyAnimation *scaleAnim = new QPropertyAnimation(&transform, "scaleX"); - scaleAnim->setStartValue(1.0); - scaleAnim->setTargetValue(2.0); - scaleAnim->setDuration(10000); - group->add(scaleAnim); - - QPropertyAnimation *scaleAnim2 = new QPropertyAnimation(&transform, "scaleY"); - scaleAnim2->setStartValue(.0); - scaleAnim2->setTargetValue(2.0); - scaleAnim2->setDuration(10000); - QEasingCurve curve(QEasingCurve::InElastic); - curve.setPeriod(2); - curve.setAmplitude(2); - - //scaleAnim2->setEasingCurve(curve); - //scaleAnim2->setEasingCurve(QEasingCurve(QEasingCurve::OutElastic , 2, 2 )); - group->add(scaleAnim2); - - QPropertyAnimation *rotAnim = new QPropertyAnimation(&transform, "rotation"); - rotAnim->setStartValue(0); - rotAnim->setTargetValue(90); - rotAnim->setDuration(10000); - group->add(rotAnim); - - group->start(); - - view.resize(800,600); - view.show(); - return app.exec(); -} diff --git a/examples/animation/research/propertytransform/propertytransform.pro b/examples/animation/research/propertytransform/propertytransform.pro deleted file mode 100644 index 94c36b8..0000000 --- a/examples/animation/research/propertytransform/propertytransform.pro +++ /dev/null @@ -1,14 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) fr 26. sep 13:21:57 2008 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -# Input -SOURCES += main.cpp -HEADERS += qpropertytransform.h -CONFIG += console - diff --git a/examples/animation/research/propertytransform/qpropertytransform.h b/examples/animation/research/propertytransform/qpropertytransform.h deleted file mode 100644 index e27987f..0000000 --- a/examples/animation/research/propertytransform/qpropertytransform.h +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include - -/** - * Experimental. - * Pros: - * 1. Does not add ugly/confusing API to QGraphicsItem. - * - * Cons: - * 1. apply() /m_item->setTransform() is called too many times. (FIXED NOW?) - * - * - */ -class QPropertyTransform : public QObject { - Q_OBJECT -public: - Q_PROPERTY(QPointF center READ center WRITE setCenter); - Q_PROPERTY(qreal rotation READ rotation WRITE setRotation); - Q_PROPERTY(qreal scaleX READ scaleX WRITE setScaleX); - Q_PROPERTY(qreal scaleY READ scaleY WRITE setScaleY); -public: - QPropertyTransform() : m_item(0), m_rotationZ(0), m_scaleX(1.), m_scaleY(1.) {} - - void setTargetItem(QGraphicsItem *item) { - m_item = item; - } - - void setCenter(const QPointF ¢er) { - m_center = center; - apply(); - } - - QPointF center() const { return m_center; } - - void setRotation(qreal rotation) { - m_rotationZ = rotation; - apply(); - } - - qreal rotation() const { return m_rotationZ; } - - void setScaleX(qreal scale) { - m_scaleX = scale; - apply(); - } - - qreal scaleX() const { return m_scaleX; } - - void setScaleY(qreal scale) { - m_scaleY = scale; - apply(); - } - - qreal scaleY() const { return m_scaleY; } - -private: - QTransform transform() const { - return QTransform().translate(m_center.x(), m_center.y()) - .rotate(m_rotationZ) - .scale(m_scaleX, m_scaleY) - .translate(-m_center.x(), -m_center.y()); - } - - void apply() { - if (m_item) - m_item->setTransform(transform()); - } - - QGraphicsItem *m_item; - QPointF m_center; - qreal m_rotationZ; - qreal m_scaleX; - qreal m_scaleY; -}; - diff --git a/examples/animation/research/sound/main.cpp b/examples/animation/research/sound/main.cpp deleted file mode 100644 index ffbc44c..0000000 --- a/examples/animation/research/sound/main.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//The purpose of this example is to show that it is possible to have your own -// animation with undefined duration - -#include -#include - -class SoundAnimation : public QAbstractAnimation -{ -public: - SoundAnimation(const QString &file) - { - //in an idea case we should also control the errors - Phonon::createPath(&m_media, &m_audio); - m_media.setCurrentSource(file); - connect(&m_media, SIGNAL(finished()), SLOT(stop())); - } - - int duration() const - { - return -1; - } - - void updateCurrentTime(int msecs) - { - //nothing to do here... - qDebug() << "updateCurrentTime" << msecs; - } - - void updateState(State state) - { - switch(state) - { - case Running: - m_media.play(); - break; - case Stopped: - m_media.stop(); - break; - case Paused: - m_media.pause(); - break; - } - } - - -private: - Phonon::MediaObject m_media; - Phonon::AudioOutput m_audio; - -}; - - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - Q_INIT_RESOURCE(sound); - - SoundAnimation anim(QLatin1String(":/media/sax.mp3")); - app.connect(&anim, SIGNAL(finished()), SLOT(quit())); - anim.start(); - - return app.exec(); -} diff --git a/examples/animation/research/sound/media/sax.mp3 b/examples/animation/research/sound/media/sax.mp3 deleted file mode 100644 index 0a078b1..0000000 Binary files a/examples/animation/research/sound/media/sax.mp3 and /dev/null differ diff --git a/examples/animation/research/sound/sound.pro b/examples/animation/research/sound/sound.pro deleted file mode 100644 index 0ad3050..0000000 --- a/examples/animation/research/sound/sound.pro +++ /dev/null @@ -1,14 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) mer. 21. janv. 13:53:26 2009 -###################################################################### - -TEMPLATE = app -QT += phonon -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -RESOURCES = sound.qrc - -# Input -SOURCES += main.cpp diff --git a/examples/animation/research/sound/sound.qrc b/examples/animation/research/sound/sound.qrc deleted file mode 100644 index 8919142..0000000 --- a/examples/animation/research/sound/sound.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - -media/sax.mp3 - - -- cgit v0.12 From 2f4f470faa12125d1bc8a0b1b353637c5749cce5 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 11:50:33 +0200 Subject: remove the citizenquartz example It's not done yet, so let's re-add it when it is. --- .../statemachine/citizenquartz/citizenquartz.pro | 20 -- .../statemachine/citizenquartz/citizenquartz.qrc | 6 - examples/statemachine/citizenquartz/clock.cpp | 390 --------------------- examples/statemachine/citizenquartz/clock.h | 62 ---- .../statemachine/citizenquartz/clockbutton.cpp | 39 --- examples/statemachine/citizenquartz/clockbutton.h | 25 -- .../statemachine/citizenquartz/clockdisplay.cpp | 139 -------- examples/statemachine/citizenquartz/clockdisplay.h | 89 ----- .../statemachine/citizenquartz/images/alarm.png | Bin 434 -> 0 bytes examples/statemachine/citizenquartz/main.cpp | 23 -- .../citizenquartz/propertyaddstate.cpp | 46 --- .../statemachine/citizenquartz/propertyaddstate.h | 33 -- .../statemachine/citizenquartz/sound/alarm.wav | Bin 3238264 -> 0 bytes examples/statemachine/citizenquartz/timeperiod.h | 84 ----- 14 files changed, 956 deletions(-) delete mode 100644 examples/statemachine/citizenquartz/citizenquartz.pro delete mode 100644 examples/statemachine/citizenquartz/citizenquartz.qrc delete mode 100644 examples/statemachine/citizenquartz/clock.cpp delete mode 100644 examples/statemachine/citizenquartz/clock.h delete mode 100644 examples/statemachine/citizenquartz/clockbutton.cpp delete mode 100644 examples/statemachine/citizenquartz/clockbutton.h delete mode 100644 examples/statemachine/citizenquartz/clockdisplay.cpp delete mode 100644 examples/statemachine/citizenquartz/clockdisplay.h delete mode 100644 examples/statemachine/citizenquartz/images/alarm.png delete mode 100644 examples/statemachine/citizenquartz/main.cpp delete mode 100644 examples/statemachine/citizenquartz/propertyaddstate.cpp delete mode 100644 examples/statemachine/citizenquartz/propertyaddstate.h delete mode 100644 examples/statemachine/citizenquartz/sound/alarm.wav delete mode 100644 examples/statemachine/citizenquartz/timeperiod.h diff --git a/examples/statemachine/citizenquartz/citizenquartz.pro b/examples/statemachine/citizenquartz/citizenquartz.pro deleted file mode 100644 index 58039a0..0000000 --- a/examples/statemachine/citizenquartz/citizenquartz.pro +++ /dev/null @@ -1,20 +0,0 @@ -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -# Input -SOURCES += main.cpp \ - clock.cpp \ - clockbutton.cpp \ - clockdisplay.cpp \ - propertyaddstate.cpp \ - -HEADERS += clock.h \ - clockbutton.h \ - clockdisplay.h \ - propertyaddstate.h \ - timeperiod.h \ - -RESOURCES += citizenquartz.qrc -CONFIG += console diff --git a/examples/statemachine/citizenquartz/citizenquartz.qrc b/examples/statemachine/citizenquartz/citizenquartz.qrc deleted file mode 100644 index fc09ef9..0000000 --- a/examples/statemachine/citizenquartz/citizenquartz.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - sound/alarm.wav - images/alarm.png - - \ No newline at end of file diff --git a/examples/statemachine/citizenquartz/clock.cpp b/examples/statemachine/citizenquartz/clock.cpp deleted file mode 100644 index 1b2b21e..0000000 --- a/examples/statemachine/citizenquartz/clock.cpp +++ /dev/null @@ -1,390 +0,0 @@ -#include "clock.h" -#include "clockbutton.h" -#include "clockdisplay.h" -#include "propertyaddstate.h" -#include "timeperiod.h" - -#include -#include -#include - -#include -#include -#include - -Clock::Clock(QGraphicsItem *parent) - : QGraphicsItem(parent), - m_stateMachine(0), - m_clockDisplay(0), - m_buttonA(0), - m_buttonB(0), - m_buttonC(0), - m_buttonD(0), - m_alarmState(0), - m_timeState(0), - m_updateState(0), - m_regularState(0), - m_displaysHistoryState(0), - m_alarmSound(new QSound(":/sound/alarm.wav", this)) -{ -} - -void Clock::initializeUi() -{ - QPainterPath path = shape(); - QPointF pap; - qreal aap; - - m_buttonA = new ClockButton("Button A", this); - pap = path.pointAtPercent(0.05); - aap = path.angleAtPercent(0.05); - m_buttonA->translate(pap.x(), pap.y()); - m_buttonA->rotate(-aap); - connect(m_buttonA, SIGNAL(pressed()), this, SIGNAL(anyButtonPressed())); - - m_buttonB = new ClockButton("Button B", this); - pap = path.pointAtPercent(0.77); - aap = path.angleAtPercent(0.77); - m_buttonB->translate(pap.x(), pap.y()); - m_buttonB->rotate(-aap); - connect(m_buttonB, SIGNAL(pressed()), this, SIGNAL(anyButtonPressed())); - - m_buttonC = new ClockButton("Button C", this); - pap = path.pointAtPercent(0.67); - aap = path.angleAtPercent(0.67); - m_buttonC->translate(pap.x(), pap.y()); - m_buttonC->rotate(-aap); - connect(m_buttonC, SIGNAL(pressed()), this, SIGNAL(anyButtonPressed())); - - m_buttonD = new ClockButton("Button D", this); - pap = path.pointAtPercent(0.57); - aap = path.angleAtPercent(0.57); - m_buttonD->translate(pap.x(), pap.y()); - m_buttonD->rotate(-aap); - connect(m_buttonD, SIGNAL(pressed()), this, SIGNAL(anyButtonPressed())); - - QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(this); - label->setText("CITIZEN"); - label->setPos(0.0 - label->boundingRect().width() / 2.0, -100.0); - - m_clockDisplay = new ClockDisplay(this); - m_clockDisplay->setCurrentTime(QDateTime::currentDateTime()); - - QTimer *timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(updateTime())); - timer->setInterval(1); - timer->start(); - m_time.start(); -} - -void Clock::initializeStateMachine() -{ - m_stateMachine = new QStateMachine; - - QState *displays = new QState(m_stateMachine->rootState()); - displays->setObjectName("displays"); - initializeDisplaysState(displays); - - QState *alarmsBeepState = new QState(m_stateMachine->rootState()); - alarmsBeepState->setObjectName("alarmsBeep"); - alarmsBeepState->invokeMethodOnEntry(this, "playSound"); - alarmsBeepState->invokeMethodOnExit(this, "stopSound"); - - QTimer *alarmTimeOut = new QTimer(alarmsBeepState); - alarmTimeOut->setInterval(30000); - alarmsBeepState->invokeMethodOnEntry(alarmTimeOut, "start"); - alarmsBeepState->invokeMethodOnExit(alarmTimeOut, "stop"); - - displays->addTransition(m_clockDisplay, SIGNAL(alarmTriggered()), alarmsBeepState); - alarmsBeepState->addTransition(this, SIGNAL(anyButtonPressed()), m_displaysHistoryState); - alarmsBeepState->addTransition(alarmTimeOut, SIGNAL(timeout()), m_displaysHistoryState); - - m_stateMachine->setInitialState(displays); - m_stateMachine->start(); -} - -void Clock::initializeUpdateState(QState *updateState) -{ - QState *sec = new QState(updateState); - sec->setObjectName("sec"); - sec->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditSecondMode); - updateState->setInitialState(sec); - - PropertyAddState *secIncrease = new PropertyAddState(updateState); - secIncrease->setObjectName("sec ++"); - secIncrease->addToProperty(m_clockDisplay, "currentTime", TimePeriod().setSeconds(1)); - sec->addTransition(m_buttonD, SIGNAL(pressed()), secIncrease); - secIncrease->addTransition(sec); - - QState *oneMin = new QState(updateState); - oneMin->setObjectName("1 min"); - oneMin->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditMinuteMode); - sec->addTransition(m_buttonC, SIGNAL(pressed()), oneMin); - - PropertyAddState *oneMinIncrease = new PropertyAddState(updateState); - oneMinIncrease->setObjectName("1 min ++"); - oneMinIncrease->addToProperty(m_clockDisplay, "currentTime", TimePeriod().setMinutes(1)); - oneMin->addTransition(m_buttonD, SIGNAL(pressed()), oneMinIncrease); - oneMinIncrease->addTransition(oneMin); - - QState *tenMin = new QState(updateState); - tenMin->setObjectName("10 min"); - tenMin->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditMinuteMode); - oneMin->addTransition(m_buttonC, SIGNAL(pressed()), tenMin); - - PropertyAddState *tenMinIncrease = new PropertyAddState(updateState); - tenMinIncrease->setObjectName("10 min ++"); - tenMinIncrease->addToProperty(m_clockDisplay, "currentTime", TimePeriod().setMinutes(10)); - tenMin->addTransition(m_buttonD, SIGNAL(pressed()), tenMinIncrease); - tenMinIncrease->addTransition(tenMin); - - QState *hr = new QState(updateState); - hr->setObjectName("hr"); - hr->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditHourMode); - tenMin->addTransition(m_buttonC, SIGNAL(pressed()), hr); - - PropertyAddState *hrIncrease = new PropertyAddState(updateState); - hrIncrease->setObjectName("hr ++"); - hrIncrease->addToProperty(m_clockDisplay, "currentTime", TimePeriod().setHours(1)); - hr->addTransition(m_buttonD, SIGNAL(pressed()), hrIncrease); - hrIncrease->addTransition(hr); - - QState *mon = new QState(updateState); - mon->setObjectName("mon"); - mon->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditMonthMode); - hr->addTransition(m_buttonC, SIGNAL(pressed()), mon); - - PropertyAddState *monIncrease = new PropertyAddState(updateState); - monIncrease->setObjectName("mon ++"); - monIncrease->addToProperty(m_clockDisplay, "currentTime", TimePeriod().setMonths(1)); - mon->addTransition(m_buttonD, SIGNAL(pressed()), monIncrease); - monIncrease->addTransition(mon); - - QState *day = new QState(updateState); - day->setObjectName("day"); - day->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditDayMode); - mon->addTransition(m_buttonC, SIGNAL(pressed()), day); - - PropertyAddState *dayIncrease = new PropertyAddState(updateState); - dayIncrease->setObjectName("day ++"); - dayIncrease->addToProperty(m_clockDisplay, "currentTime", TimePeriod().setDays(1)); - day->addTransition(m_buttonD, SIGNAL(pressed()), dayIncrease); - dayIncrease->addTransition(day); - - QState *year = new QState(updateState); - year->setObjectName("year"); - year->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditYearMode); - day->addTransition(m_buttonC, SIGNAL(pressed()), year); - - PropertyAddState *yearIncrease = new PropertyAddState(updateState); - yearIncrease->setObjectName("year ++"); - yearIncrease->addToProperty(m_clockDisplay, "currentTime", TimePeriod().setYears(1)); - year->addTransition(m_buttonD, SIGNAL(pressed()), yearIncrease); - yearIncrease->addTransition(year); - year->addTransition(m_buttonC, SIGNAL(pressed()), m_timeState); -} - -void Clock::initializeRegularState(QState *regular) -{ - m_timeState = new QState(regular); - m_timeState->setObjectName("time"); - m_timeState->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::CurrentTimeMode); - - QState *date = new QState(regular); - date->setObjectName("date"); - date->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::CurrentDateMode); - - QState *dateTimerState = new QState(date); - dateTimerState->setObjectName("dateTimerState"); - - // Date state exits after 2 m - QTimer *dateTimer = new QTimer(dateTimerState); - dateTimer->setSingleShot(true); - dateTimer->setInterval(2*60000); - dateTimerState->invokeMethodOnEntry(dateTimer, "start"); - dateTimerState->invokeMethodOnExit(dateTimer, "stop"); - - date->setInitialState(dateTimerState); - - m_updateState = new QState(regular); - m_updateState->setObjectName("update"); - - // Update state exits after 2 m - QTimer *updateTimer = new QTimer(m_updateState); - updateTimer->setSingleShot(true); - updateTimer->setInterval(2 * 60000); - m_updateState->invokeMethodOnEntry(updateTimer, "start"); - m_updateState->invokeMethodOnExit(updateTimer, "stop"); - - initializeUpdateState(m_updateState); - - m_timeState->addTransition(m_buttonD, SIGNAL(pressed()), date); - date->addTransition(m_buttonD, SIGNAL(pressed()), m_timeState); - date->addTransition(dateTimer, SIGNAL(timeout()), m_timeState); - - m_updateState->addTransition(updateTimer, SIGNAL(timeout()), m_timeState); - m_updateState->addTransition(m_buttonB, SIGNAL(pressed()), m_timeState); - - regular->setInitialState(m_timeState); -} - -void Clock::initializeAlarmUpdateState(QState *update) -{ - QState *hr = new QState(update); - hr->setObjectName("hr"); - hr->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditAlarmHourMode); - - PropertyAddState *hrInc = new PropertyAddState(update); - hrInc->setObjectName("hr ++"); - hrInc->addToProperty(m_clockDisplay, "alarm", TimePeriod().setHours(1)); - hr->addTransition(m_buttonD, SIGNAL(pressed()), hrInc); - hrInc->addTransition(hr); - - QState *tenMin = new QState(update); - tenMin->setObjectName("10 min"); - tenMin->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditAlarmTenMinuteMode); - hr->addTransition(m_buttonC, SIGNAL(pressed()), tenMin); - - PropertyAddState *tenMinInc = new PropertyAddState(update); - tenMinInc->setObjectName("10 min ++"); - tenMinInc->addToProperty(m_clockDisplay, "alarm", TimePeriod().setMinutes(10)); - tenMin->addTransition(m_buttonD, SIGNAL(pressed()), tenMinInc); - tenMinInc->addTransition(tenMin); - - QState *oneMin = new QState(update); - oneMin->setObjectName("1 min"); - oneMin->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::EditAlarmMinuteMode); - tenMin->addTransition(m_buttonC, SIGNAL(pressed()), oneMin); - - PropertyAddState *oneMinInc = new PropertyAddState(update); - oneMinInc->setObjectName("1 min ++"); - oneMinInc->addToProperty(m_clockDisplay, "alarm", TimePeriod().setMinutes(1)); - oneMin->addTransition(m_buttonD, SIGNAL(pressed()), oneMinInc); - oneMinInc->addTransition(oneMin); - - oneMin->addTransition(m_buttonC, SIGNAL(pressed()), m_alarmState); - m_alarmState->addTransition(m_buttonC, SIGNAL(pressed()), hr); -} - -void Clock::initializeOutState(QState *out) -{ - m_alarmState = new QState(out); - m_alarmState->setObjectName("alarmState"); - m_alarmState->setPropertyOnEntry(m_clockDisplay, "displayMode", ClockDisplay::AlarmMode); - initializeAlarmState(m_alarmState); - out->setInitialState(m_alarmState); - - QState *alarmUpdate = new QState(out); - alarmUpdate->setObjectName("alarmUpdate"); - initializeAlarmUpdateState(alarmUpdate); - - alarmUpdate->addTransition(m_buttonB, SIGNAL(pressed()), m_alarmState); - m_alarmState->addTransition(m_buttonA, SIGNAL(pressed()), m_regularState); -} - -void Clock::initializeDisplaysState(QState *displays) -{ - m_regularState = new QState(displays); - m_regularState->setObjectName("regular"); - initializeRegularState(m_regularState); - displays->setInitialState(m_regularState); - - QState *out = new QState(displays); - out->setObjectName("out"); - - QTimer *outTimer = new QTimer(out); - outTimer->setSingleShot(true); - outTimer->setInterval(2 * 60000); - out->invokeMethodOnEntry(outTimer, "start"); - out->invokeMethodOnExit(outTimer, "stop"); - - initializeOutState(out); - - QState *wait = new QState(displays); - wait->setObjectName("wait"); - - QTimer *waitTimer = new QTimer(wait); - waitTimer->setSingleShot(true); - waitTimer->setInterval(2000); - wait->invokeMethodOnEntry(waitTimer, "start"); - wait->invokeMethodOnExit(waitTimer, "stop"); - - m_displaysHistoryState = displays->addHistoryState(QState::DeepHistory); - - m_timeState->addTransition(m_buttonC, SIGNAL(pressed()), wait); - wait->addTransition(waitTimer, SIGNAL(timeout()), m_updateState); - wait->addTransition(m_buttonC, SIGNAL(released()), m_timeState); - m_timeState->addTransition(m_buttonA, SIGNAL(pressed()), m_alarmState); - out->addTransition(outTimer, SIGNAL(timeout()), m_regularState); -} - -void Clock::initializeAlarmState(QState *alarmState) -{ - QState *offState = new QState(alarmState); - offState->setObjectName("alarmOff"); - offState->setPropertyOnEntry(m_clockDisplay, "alarmEnabled", false); - - QState *onState = new QState(alarmState); - onState->setObjectName("alarmOn"); - onState->setPropertyOnEntry(m_clockDisplay, "alarmEnabled", true); - - QHistoryState *history = alarmState->addHistoryState(); - history->setObjectName("alarmHistory"); - history->setDefaultState(offState); - - offState->addTransition(m_buttonD, SIGNAL(pressed()), onState); - onState->addTransition(m_buttonD, SIGNAL(pressed()), offState); - - QState *intermediate = new QState(alarmState); - intermediate->addTransition(history); - - alarmState->setInitialState(intermediate); -} - -QRectF Clock::boundingRect() const -{ - return shape().boundingRect(); -} - -QPainterPath Clock::shape() const -{ - QPainterPath path; - path.addRoundedRect(QRectF(-140.0, -100.0, 280.0, 200.0), 50.0, 50.0, Qt::RelativeSize); - - return path; -} - -void Clock::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - painter->setPen(Qt::black); - painter->setBrush(Qt::NoBrush); - - // Clock face - painter->drawPath(shape()); -} - -void Clock::updateTime() -{ - int elapsed = m_time.elapsed(); - if (elapsed > 0) { - m_time.restart(); - QDateTime currentTime = m_clockDisplay->currentTime(); - m_clockDisplay->setCurrentTime(currentTime.addMSecs(elapsed)); - - update(); - } -} - -void Clock::playSound() -{ - qDebug("playing sound"); - m_alarmSound->stop(); - m_alarmSound->play(); -} - -void Clock::stopSound() -{ - qDebug("stopping sound"); - m_alarmSound->stop(); -} - diff --git a/examples/statemachine/citizenquartz/clock.h b/examples/statemachine/citizenquartz/clock.h deleted file mode 100644 index afd6433..0000000 --- a/examples/statemachine/citizenquartz/clock.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef CLOCK_H -#define CLOCK_H - -#include -#include - -class ClockButton ; -class ClockDisplay ; -class QStateMachine ; -class QState ; -class QTimerState ; -class QSound ; -class QHistoryState ; - -class Clock: public QObject, public QGraphicsItem -{ - Q_OBJECT -public: - Clock(QGraphicsItem *parent = 0); - - void initializeUi(); - void initializeStateMachine(); - - virtual QRectF boundingRect() const; - virtual QPainterPath shape() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); - -signals: - void anyButtonPressed(); - -public slots: - void updateTime(); - void playSound(); - void stopSound(); - -private: - void initializeDisplaysState(QState *displays); - void initializeAlarmState(QState *alarmState); - void initializeRegularState(QState *regular); - void initializeUpdateState(QState *update); - void initializeOutState(QState *out); - void initializeAlarmUpdateState(QState *update); - - QStateMachine *m_stateMachine; - ClockDisplay *m_clockDisplay; - ClockButton *m_buttonA; - ClockButton *m_buttonB; - ClockButton *m_buttonC; - ClockButton *m_buttonD; - - QState *m_alarmState; - QState *m_timeState; - QState *m_updateState; - QState *m_regularState; - - QHistoryState *m_displaysHistoryState; - - QSound *m_alarmSound; - QTime m_time; -}; - -#endif // CLOCK_H diff --git a/examples/statemachine/citizenquartz/clockbutton.cpp b/examples/statemachine/citizenquartz/clockbutton.cpp deleted file mode 100644 index 7b86891..0000000 --- a/examples/statemachine/citizenquartz/clockbutton.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "clockbutton.h" - -#include - -ClockButton::ClockButton(const QString &name, QGraphicsItem *parent) : QGraphicsItem(parent) -{ - setObjectName(name); - setToolTip(name); - setAcceptedMouseButtons(Qt::LeftButton); -} - -QRectF ClockButton::boundingRect() const -{ - return QRectF(-10.0, -10.0, 20.0, 20.0); -} - -QPainterPath ClockButton::shape() const -{ - QPainterPath path; - path.addRoundedRect(boundingRect(), 15.0, 15.0, Qt::RelativeSize); - - return path; -} - -void ClockButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - painter->setBrush(Qt::black); - painter->drawPath(shape()); -} - -void ClockButton::mousePressEvent(QGraphicsSceneMouseEvent *) -{ - emit pressed(); -} - -void ClockButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - emit released(); -} \ No newline at end of file diff --git a/examples/statemachine/citizenquartz/clockbutton.h b/examples/statemachine/citizenquartz/clockbutton.h deleted file mode 100644 index 02a7ccd..0000000 --- a/examples/statemachine/citizenquartz/clockbutton.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef CLOCKBUTTON_H -#define CLOCKBUTTON_H - -#include - -class ClockButton: public QObject, public QGraphicsItem -{ - Q_OBJECT -public: - ClockButton(const QString &name, QGraphicsItem *parent = 0); - - virtual QRectF boundingRect() const; - virtual QPainterPath shape() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); - -protected: - virtual void mousePressEvent(QGraphicsSceneMouseEvent *); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - -signals: - void pressed(); - void released(); -}; - -#endif //CLOCKBUTTON_H diff --git a/examples/statemachine/citizenquartz/clockdisplay.cpp b/examples/statemachine/citizenquartz/clockdisplay.cpp deleted file mode 100644 index db026f5..0000000 --- a/examples/statemachine/citizenquartz/clockdisplay.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include "clockdisplay.h" - -#include -#include - -ClockDisplay::ClockDisplay(QGraphicsItem *parent) - : QGraphicsItem(parent), - m_displayMode(CurrentTimeMode), - m_currentTime(QDate(1970, 1, 1), QTime(0, 0)), - m_alarm(0, 0), - m_alarmEnabled(false), - m_blink(false) - -{ - m_text = new QGraphicsTextItem(this); - - QTimer *timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(toggleBlinkFlag())); - timer->start(500); - - QFont font = m_text->font(); - font.setPointSizeF(20.0); - m_text->setFont(font); - - m_text->translate(-100.0, -20.0); - - QPixmap pm(":/images/alarm.png"); - m_alarmSymbol = new QGraphicsPixmapItem(pm, this); - m_alarmSymbol->translate(-100.0, -60.0); - m_alarmSymbol->setOffset(5.0, 5.0); - m_alarmSymbol->scale(0.5, 0.5); -} - -ClockDisplay::~ClockDisplay() -{ -} - -void ClockDisplay::toggleBlinkFlag() -{ - m_blink = !m_blink; - update(); -} - -void ClockDisplay::updateText() -{ - switch (m_displayMode) { - case EditSecondMode: - if (m_blink) { - m_text->setHtml(m_currentTime.toString("hh:mm:''ss''")); - break; - } - // fall throoough - case EditMinuteMode: - if (m_blink) { - m_text->setHtml(m_currentTime.toString("hh:''mm'':ss")); - break; - } - - // fall throoough - case EditHourMode: - if (m_blink) { - m_text->setHtml(m_currentTime.toString("''hh'':mm:ss")); - break; - } - - // fall throoough - case CurrentTimeMode: - m_text->setHtml(m_currentTime.toString("hh:mm:ss")); - break; - - case EditMonthMode: - if (m_blink) { - m_text->setHtml(m_currentTime.toString("yyyy.''MM''.dd")); - break; - } - - // fall throoough - case EditDayMode: - if (m_blink) { - m_text->setHtml(m_currentTime.toString("yyyy.MM.''dd''")); - break; - } - - // fall throoough - case EditYearMode: - if (m_blink) { - m_text->setHtml(m_currentTime.toString("''yyyy''.MM.dd")); - break; - } - - // fall throoough - case CurrentDateMode: - m_text->setHtml(m_currentTime.toString("yyyy.MM.dd")); - break; - - case EditAlarmHourMode: - if (m_blink) { - m_text->setHtml(m_alarm.toString("''hh'':mm")); - break; - } - - // fall throooough - case EditAlarmTenMinuteMode: - case EditAlarmMinuteMode: - if (m_blink) { - m_text->setHtml(m_alarm.toString("hh:''mm''")); - break; - } - - // fall throoough - case AlarmMode: - m_text->setHtml(m_alarm.toString("hh:mm")); - break; - - default: - m_text->setHtml("Not implemented"); - }; -} - -QRectF ClockDisplay::boundingRect() const -{ - return QRectF(-100.0, -60.0, 200.0, 120.0); -} - -void ClockDisplay::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - m_alarmSymbol->setVisible(m_alarmEnabled); - - updateText(); - - // Screen - painter->drawRoundedRect(boundingRect(), 15.0, 15.0, Qt::RelativeSize); - - // Button grid - painter->drawLine(QPointF(-100.0, -20.0), QPointF(100.0, -20.0)); - painter->drawLine(QPointF(-50.0, -60.0), QPointF(-50.0, -20.0)); - painter->drawLine(QPointF(0.0, -60.0), QPointF(0.0, -20.0)); - painter->drawLine(QPointF(50.0, -60.0), QPointF(50.0, -20.0)); -} diff --git a/examples/statemachine/citizenquartz/clockdisplay.h b/examples/statemachine/citizenquartz/clockdisplay.h deleted file mode 100644 index ec86509..0000000 --- a/examples/statemachine/citizenquartz/clockdisplay.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef CLOCKDISPLAY_H -#define CLOCKDISPLAY_H - -#include -#include -#include - -class ClockDisplay: public QObject, public QGraphicsItem -{ - Q_OBJECT - Q_ENUMS(DisplayMode) - Q_PROPERTY(DisplayMode displayMode READ displayMode WRITE setDisplayMode) - Q_PROPERTY(QDateTime currentTime READ currentTime WRITE setCurrentTime) - Q_PROPERTY(QTime alarm READ alarm WRITE setAlarm) - Q_PROPERTY(bool alarmEnabled READ alarmEnabled WRITE setAlarmEnabled) -public: - enum DisplayMode { - CurrentTimeMode, - EditSecondMode, - EditMinuteMode, - EditHourMode, - - CurrentDateMode, - EditMonthMode, - EditDayMode, - EditYearMode, - - AlarmMode, - EditAlarmHourMode, - EditAlarmTenMinuteMode, - EditAlarmMinuteMode, - - ChimeMode, - StopWatchMode, - ModeCount - }; - - ClockDisplay(QGraphicsItem *parent = 0); - virtual ~ClockDisplay(); - - void setDisplayMode(DisplayMode displayMode) { m_displayMode = displayMode; update(); } - DisplayMode displayMode() const { return m_displayMode; } - - QDateTime currentTime() const { return m_currentTime; } - void setCurrentTime(const QDateTime &time) - { - if (m_alarmEnabled && !alarmMatches(m_currentTime) && alarmMatches(time)) - emit alarmTriggered(); - m_currentTime = time; - update(); - } - - QTime alarm() const { return m_alarm; } - void setAlarm(const QTime &time) { m_alarm = time; update(); } - - bool alarmEnabled() const { return m_alarmEnabled; } - void setAlarmEnabled(bool enabled) { m_alarmEnabled = enabled; update(); } - - virtual QRectF boundingRect() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); - -signals: - void alarmTriggered(); - -private slots: - void toggleBlinkFlag(); - -private: - void updateText(); - - bool alarmMatches(const QDateTime &dt) - { - return (dt.time().hour() == m_alarm.hour() && dt.time().minute() == m_alarm.minute()); - } - - DisplayMode m_displayMode; - - QDateTime m_currentTime; - QTime m_alarm; - - QGraphicsTextItem *m_text; - QGraphicsPixmapItem *m_alarmSymbol; - - uint m_alarmEnabled : 1; - uint m_blink : 1; - uint m_reserved : 30; -}; - -#endif diff --git a/examples/statemachine/citizenquartz/images/alarm.png b/examples/statemachine/citizenquartz/images/alarm.png deleted file mode 100644 index a19778d..0000000 Binary files a/examples/statemachine/citizenquartz/images/alarm.png and /dev/null differ diff --git a/examples/statemachine/citizenquartz/main.cpp b/examples/statemachine/citizenquartz/main.cpp deleted file mode 100644 index 2c6b14c..0000000 --- a/examples/statemachine/citizenquartz/main.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include - -#include "clock.h" - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - QGraphicsScene scene; - - Clock *clock = new Clock; - clock->initializeUi(); - clock->initializeStateMachine(); - scene.addItem(clock); - - QGraphicsView view(&scene); - view.setRenderHint(QPainter::Antialiasing); - view.show(); - - return app.exec(); -} diff --git a/examples/statemachine/citizenquartz/propertyaddstate.cpp b/examples/statemachine/citizenquartz/propertyaddstate.cpp deleted file mode 100644 index dd23948..0000000 --- a/examples/statemachine/citizenquartz/propertyaddstate.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "PropertyAddState.h" -#include "timeperiod.h" - -#include -#include - -PropertyAddState::PropertyAddState(QState *parent) - : QState(parent) -{ -} - -void PropertyAddState::addToProperty(QObject *object, const char *propertyName, - const QVariant &valueToAdd) -{ - m_propertyAdditions.append(PropertyAdder(object, propertyName, valueToAdd)); -} - -QVariant PropertyAddState::addProperties(const QVariant ¤t, const QVariant &toAdd) const -{ - QVariant result; - switch (current.type()) { - case QVariant::DateTime: - result = current.toDateTime() + qvariant_cast(toAdd); - break; - case QVariant::Time: - result = current.toTime() + qvariant_cast(toAdd); - break; - default: - qWarning("PropertyAddState::addProperties: QVariant type '%s' not supported", - current.typeName()); - }; - - return result; -} - -void PropertyAddState::onEntry() -{ - foreach (PropertyAdder propertyAdder, m_propertyAdditions) { - QObject *object = propertyAdder.object; - QByteArray propertyName = propertyAdder.propertyName; - QVariant toAdd = propertyAdder.valueToAdd; - QVariant current = object->property(propertyName); - - object->setProperty(propertyName, addProperties(current, toAdd)); - } -} diff --git a/examples/statemachine/citizenquartz/propertyaddstate.h b/examples/statemachine/citizenquartz/propertyaddstate.h deleted file mode 100644 index 4d28055..0000000 --- a/examples/statemachine/citizenquartz/propertyaddstate.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef PropertyAddState_H -#define PropertyAddState_H - -#include - -#include -#include - -class PropertyAddState: public QState -{ -public: - PropertyAddState(QState *parent = 0); - - void addToProperty(QObject *object, const char *propertyName, const QVariant &valueToAdd); - virtual void onEntry(); - -private: - QVariant addProperties(const QVariant ¤t, const QVariant &toAdd) const; - - struct PropertyAdder { - PropertyAdder(QObject *_object, const char *_propertyName, const QVariant &_valueToAdd) - : object(_object), propertyName(_propertyName), valueToAdd(_valueToAdd) - { - } - - QObject *object; - QByteArray propertyName; - QVariant valueToAdd; - }; - QList m_propertyAdditions; -}; - -#endif // PropertyAddState_H diff --git a/examples/statemachine/citizenquartz/sound/alarm.wav b/examples/statemachine/citizenquartz/sound/alarm.wav deleted file mode 100644 index 1d9486f..0000000 Binary files a/examples/statemachine/citizenquartz/sound/alarm.wav and /dev/null differ diff --git a/examples/statemachine/citizenquartz/timeperiod.h b/examples/statemachine/citizenquartz/timeperiod.h deleted file mode 100644 index c5a3a16..0000000 --- a/examples/statemachine/citizenquartz/timeperiod.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef TIMEPERIOD_H -#define TIMEPERIOD_H - -#include -#include -#include - -class TimePeriod -{ -public: - TimePeriod() : m_seconds(0), m_minutes(0), m_hours(0), m_days(0), m_months(0), m_years(0) - { - } - - TimePeriod &setSeconds(int seconds) { m_seconds = seconds; return *this; } - int seconds() const { return m_seconds; } - - TimePeriod &setMinutes(int minutes) { m_minutes = minutes; return *this; } - int minutes() const { return m_minutes; } - - TimePeriod &setHours(int hours) { m_hours = hours; return *this; } - int hours() const { return m_hours; } - - TimePeriod &setDays(int days) { m_days = days; return *this; } - int days() const { return m_days; } - - TimePeriod &setMonths(int months) { m_months = months; return *this; } - int months() const { return m_months; } - - TimePeriod &setYears(int years) { m_years = years; return *this; } - int years() const { return m_years; } - - operator QVariant() const - { - QVariant v; - qVariantSetValue(v, *this); - return v; - } - -private: - int m_seconds; - int m_minutes; - int m_hours; - int m_days; - int m_months; - int m_years; -}; - -inline void operator+=(QDateTime &dateTime, const TimePeriod &timePeriod) -{ - dateTime = dateTime.addSecs(timePeriod.seconds()); - dateTime = dateTime.addSecs(timePeriod.minutes() * 60); - dateTime = dateTime.addSecs(timePeriod.hours() * 3600); - dateTime = dateTime.addDays(timePeriod.days()); - dateTime = dateTime.addMonths(timePeriod.months()); - dateTime = dateTime.addYears(timePeriod.years()); -} - -inline QDateTime operator+(const QDateTime &dateTime, const TimePeriod &timePeriod) -{ - QDateTime result(dateTime); - result += timePeriod; - - return result; -} - -inline void operator+=(QTime &time, const TimePeriod &timePeriod) -{ - time = time.addSecs(timePeriod.seconds()); - time = time.addSecs(timePeriod.minutes() * 60); - time = time.addSecs(timePeriod.hours() * 3600); -} - -inline QTime operator+(const QTime &time, const TimePeriod &timePeriod) -{ - QTime result(time); - result += timePeriod; - - return result; -} - -Q_DECLARE_METATYPE(TimePeriod) - -#endif \\ TIMEPERIOD_H -- cgit v0.12 From 74ca1734cd6c69e7827a7a66b0c0db5face7752f Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 12:53:59 +0200 Subject: kill experimental QtAnimation module stuff, the module doesn't exist anymore --- bin/syncqt | 2 -- mkspecs/features/qt.prf | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/bin/syncqt b/bin/syncqt index 5ac8933..7a9f1d3 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -23,7 +23,6 @@ my $basedir = $ENV{"QTDIR"}; $basedir =~ s=\\=/=g; my %modules = ( # path to module name map "QtGui" => "$basedir/src/gui", - "QtAnimation" => "$basedir/src/animation", "QtOpenGL" => "$basedir/src/opengl", "QtCore" => "$basedir/src/corelib", "QtXml" => "$basedir/src/xml", @@ -681,7 +680,6 @@ foreach (@modules_to_sync) { foreach(split(/ /, "$1")) { $master_contents .= "#include \n" if("$_" eq "core"); $master_contents .= "#include \n" if("$_" eq "gui"); - $master_contents .= "#include \n" if("$_" eq "experimental-animation"); $master_contents .= "#include \n" if("$_" eq "network"); $master_contents .= "#include \n" if("$_" eq "svg"); $master_contents .= "#include \n" if("$_" eq "script"); diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 3ef864e..0c6e09a 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -36,7 +36,7 @@ INCLUDEPATH = $$QMAKE_INCDIR_QT $$INCLUDEPATH #prepending prevents us from picki win32:INCLUDEPATH += $$QMAKE_INCDIR_QT/ActiveQt # As order does matter for static libs, we reorder the QT variable here -TMPLIBS = webkit phonon dbus testlib script scripttools svg qt3support sql xmlpatterns xml opengl experimental-animation gui network core +TMPLIBS = webkit phonon dbus testlib script scripttools svg qt3support sql xmlpatterns xml opengl gui network core for(QTLIB, $$list($$TMPLIBS)) { contains(QT, $$QTLIB): QT_ORDERED += $$QTLIB } @@ -147,7 +147,6 @@ for(QTLIB, $$list($$lower($$unique(QT)))) { else:isEqual(QTLIB, svg):qlib = QtSvg else:isEqual(QTLIB, script):qlib = QtScript else:isEqual(QTLIB, scripttools):qlib = QtScriptTools - else:isEqual(QTLIB, experimental-animation):qlib = QtAnimation else:isEqual(QTLIB, testlib):qlib = QtTest else:isEqual(QTLIB, dbus):qlib = QtDBus else:isEqual(QTLIB, phonon):qlib = phonon -- cgit v0.12 From 87f51bd2526130f1b3c79d59aec89fe078094d68 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 12:58:57 +0200 Subject: update the qdoc tags (\since 4.6, remove \preliminary) --- src/corelib/animation/qabstractanimation.cpp | 3 +-- src/corelib/animation/qanimationgroup.cpp | 3 +-- src/corelib/animation/qparallelanimationgroup.cpp | 3 +-- src/corelib/animation/qpauseanimation.cpp | 3 +-- src/corelib/animation/qpropertyanimation.cpp | 2 +- src/corelib/animation/qsequentialanimationgroup.cpp | 3 +-- src/corelib/animation/qvariantanimation.cpp | 3 +-- src/corelib/tools/qeasingcurve.cpp | 1 + 8 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 759cf18..94a94d1 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -43,8 +43,7 @@ \class QAbstractAnimation \ingroup animation \brief The QAbstractAnimation class is the base of all animations. - \since 4.5 - \preliminary + \since 4.6 The class defines the functions for the functionality shared by all animations. By inheriting this class, you can create custom diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp index e78ce9a..ed06eff 100644 --- a/src/corelib/animation/qanimationgroup.cpp +++ b/src/corelib/animation/qanimationgroup.cpp @@ -42,9 +42,8 @@ /*! \class QAnimationGroup \brief The QAnimationGroup class is an abstract base class for groups of animations. - \since 4.5 + \since 4.6 \ingroup animation - \preliminary An animation group is a container for animations (subclasses of QAbstractAnimation). A group is usually responsible for managing diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index 48c8b3e..13f6073 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -42,9 +42,8 @@ /*! \class QParallelAnimationGroup \brief The QParallelAnimationGroup class provides a parallel group of animations. - \since 4.5 + \since 4.6 \ingroup animation - \preliminary QParallelAnimationGroup--a \l{QAnimationGroup}{container for animations}--starts all its animations when it is diff --git a/src/corelib/animation/qpauseanimation.cpp b/src/corelib/animation/qpauseanimation.cpp index c853745..b175f0c 100644 --- a/src/corelib/animation/qpauseanimation.cpp +++ b/src/corelib/animation/qpauseanimation.cpp @@ -42,9 +42,8 @@ /*! \class QPauseAnimation \brief The QPauseAnimation class provides a pause for QSequentialAnimationGroup. - \since 4.5 + \since 4.6 \ingroup animation - \preliminary If you wish to introduce a delay between animations in a QSequentialAnimationGroup, you can insert a QPauseAnimation. This diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index 10fe8a2..9a17049 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -42,8 +42,8 @@ /*! \class QPropertyAnimation \brief The QPropertyAnimation class animates Qt properties + \since 4.6 \ingroup animation - \preliminary QPropertyAnimation interpolates over \l{Qt's Property System}{Qt properties}. As property values are stored in \l{QVariant}s, the diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp index 38f4818..14814a7 100644 --- a/src/corelib/animation/qsequentialanimationgroup.cpp +++ b/src/corelib/animation/qsequentialanimationgroup.cpp @@ -42,9 +42,8 @@ /*! \class QSequentialAnimationGroup \brief The QSequentialAnimationGroup class provides a sequential group of animations. - \since 4.5 + \since 4.6 \ingroup animation - \preliminary QSequentialAnimationGroup is a QAnimationGroup that runs its animations in sequence, i.e., it starts one animation after diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 864575a..a6834bb 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -56,8 +56,7 @@ QT_BEGIN_NAMESPACE \class QVariantAnimation \ingroup animation \brief The QVariantAnimation class provides an abstract base class for animations. - \since 4.5 - \preliminary + \since 4.6 This class is part of \l{The Animation Framework}. It serves as a base class for property and item animations, with functions for diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 23eb2a6..34765c8 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -53,6 +53,7 @@ /*! \class QEasingCurve + \since 4.6 \ingroup animation \brief The QEasingCurve class provides easing curves for controlling animation. -- cgit v0.12 From dfdb8555afc5a7e69c25c5a0c8b98167f15f51e5 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 13:18:35 +0200 Subject: remove QT_EXPERIMENTAL stuff --- src/corelib/global/qglobal.h | 16 ---------------- src/corelib/tools/qtimeline.h | 2 -- src/gui/graphicsview/qgraphicswidget.h | 1 - src/gui/statemachine/qbasickeyeventtransition.cpp | 8 +------- src/gui/statemachine/qbasickeyeventtransition_p.h | 7 +------ src/gui/statemachine/qbasicmouseeventtransition.cpp | 7 +------ src/gui/statemachine/qbasicmouseeventtransition_p.h | 7 +------ src/gui/statemachine/qkeyeventtransition.cpp | 7 +------ src/gui/statemachine/qkeyeventtransition.h | 7 ++----- src/gui/statemachine/qmouseeventtransition.cpp | 7 +------ src/gui/statemachine/qmouseeventtransition.h | 8 ++------ 11 files changed, 10 insertions(+), 67 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index a0ea68c..36d87e2 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -128,22 +128,6 @@ namespace QT_NAMESPACE {} #endif /* __cplusplus */ -/** - * For animation framework to work seamlessly as a solution - */ -#if 0 -# define QT_EXPERIMENTAL_BEGIN_NAMESPACE namespace QtExperimental { -# define QT_EXPERIMENTAL_END_NAMESPACE } -# define QT_EXPERIMENTAL_USE_NAMESPACE using namespace QtExperimental; -# define QT_EXPERIMENTAL_PREPEND_NAMESPACE(name) QtExperimental::name -namespace QtExperimental {} -#else -# define QT_EXPERIMENTAL_BEGIN_NAMESPACE -# define QT_EXPERIMENTAL_END_NAMESPACE -# define QT_EXPERIMENTAL_USE_NAMESPACE -# define QT_EXPERIMENTAL_PREPEND_NAMESPACE(name) name -#endif - #if defined(Q_OS_MAC) && !defined(Q_CC_INTEL) #define QT_BEGIN_HEADER extern "C++" { #define QT_END_HEADER } diff --git a/src/corelib/tools/qtimeline.h b/src/corelib/tools/qtimeline.h index 314dd7c..48c9232 100644 --- a/src/corelib/tools/qtimeline.h +++ b/src/corelib/tools/qtimeline.h @@ -45,8 +45,6 @@ #include #include -QT_EXPERIMENTAL_USE_NAMESPACE - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 05195b6..65fd219 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -59,7 +59,6 @@ class QGraphicsLayout; class QGraphicsSceneMoveEvent; class QGraphicsWidgetPrivate; class QGraphicsSceneResizeEvent; -class QGraphicsWidgetAnimator; class QStyle; class QStyleOption; diff --git a/src/gui/statemachine/qbasickeyeventtransition.cpp b/src/gui/statemachine/qbasickeyeventtransition.cpp index 7f515cd..fe89f81 100644 --- a/src/gui/statemachine/qbasickeyeventtransition.cpp +++ b/src/gui/statemachine/qbasickeyeventtransition.cpp @@ -12,13 +12,7 @@ #include "qbasickeyeventtransition_p.h" #include #include - -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qabstracttransition_p.h" -#else -# include -#endif - +#include QT_BEGIN_NAMESPACE diff --git a/src/gui/statemachine/qbasickeyeventtransition_p.h b/src/gui/statemachine/qbasickeyeventtransition_p.h index 7506747..c4ff863 100644 --- a/src/gui/statemachine/qbasickeyeventtransition_p.h +++ b/src/gui/statemachine/qbasickeyeventtransition_p.h @@ -23,12 +23,7 @@ // We mean it. // -// Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qabstracttransition.h" -#else -# include -#endif +#include #include QT_BEGIN_NAMESPACE diff --git a/src/gui/statemachine/qbasicmouseeventtransition.cpp b/src/gui/statemachine/qbasicmouseeventtransition.cpp index 42b7580..a18d1e8 100644 --- a/src/gui/statemachine/qbasicmouseeventtransition.cpp +++ b/src/gui/statemachine/qbasicmouseeventtransition.cpp @@ -13,12 +13,7 @@ #include #include #include - -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qabstracttransition_p.h" -#else -# include -#endif +#include QT_BEGIN_NAMESPACE diff --git a/src/gui/statemachine/qbasicmouseeventtransition_p.h b/src/gui/statemachine/qbasicmouseeventtransition_p.h index 57f83c6..6a3ad1e 100644 --- a/src/gui/statemachine/qbasicmouseeventtransition_p.h +++ b/src/gui/statemachine/qbasicmouseeventtransition_p.h @@ -23,12 +23,7 @@ // We mean it. // -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qabstracttransition.h" -#else -# include -#endif - +#include #include QT_BEGIN_NAMESPACE diff --git a/src/gui/statemachine/qkeyeventtransition.cpp b/src/gui/statemachine/qkeyeventtransition.cpp index 3cf51a3..0418501 100644 --- a/src/gui/statemachine/qkeyeventtransition.cpp +++ b/src/gui/statemachine/qkeyeventtransition.cpp @@ -12,12 +12,7 @@ #include "qkeyeventtransition.h" #include "qbasickeyeventtransition_p.h" #include - -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qeventtransition_p.h" -#else -# include -#endif +#include QT_BEGIN_NAMESPACE diff --git a/src/gui/statemachine/qkeyeventtransition.h b/src/gui/statemachine/qkeyeventtransition.h index 08595e8..08c4800 100644 --- a/src/gui/statemachine/qkeyeventtransition.h +++ b/src/gui/statemachine/qkeyeventtransition.h @@ -12,11 +12,8 @@ #ifndef QKEYEVENTTRANSITION_H #define QKEYEVENTTRANSITION_H -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qeventtransition.h" -#else -# include -#endif +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/gui/statemachine/qmouseeventtransition.cpp b/src/gui/statemachine/qmouseeventtransition.cpp index 5ffdab0..ae3c407 100644 --- a/src/gui/statemachine/qmouseeventtransition.cpp +++ b/src/gui/statemachine/qmouseeventtransition.cpp @@ -13,12 +13,7 @@ #include "qbasicmouseeventtransition_p.h" #include #include - -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qeventtransition_p.h" -#else -# include -#endif +#include QT_BEGIN_NAMESPACE diff --git a/src/gui/statemachine/qmouseeventtransition.h b/src/gui/statemachine/qmouseeventtransition.h index e878a58..aedc5c2 100644 --- a/src/gui/statemachine/qmouseeventtransition.h +++ b/src/gui/statemachine/qmouseeventtransition.h @@ -12,12 +12,8 @@ #ifndef QMOUSEEVENTTRANSITION_H #define QMOUSEEVENTTRANSITION_H -//Qt -#if defined(QT_EXPERIMENTAL_SOLUTION) -# include "qeventtransition.h" -#else -# include -#endif +#include + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -- cgit v0.12 From ee550f157d4c9ca7816a75ac344d1c32eaf1f2b1 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 13:27:30 +0200 Subject: add README file for examples/animation --- examples/animation/README | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 examples/animation/README diff --git a/examples/animation/README b/examples/animation/README new file mode 100644 index 0000000..6a892f8 --- /dev/null +++ b/examples/animation/README @@ -0,0 +1,38 @@ +The animation framework aims to provide an easy way for creating animated and +smooth GUI's. By animating Qt properties, the framework provides great freedom +for animating widgets and other QObjects. The framework can also be used with +the Graphics View framework. + +The example launcher provided with Qt can be used to explore each of the +examples in this directory. + +Documentation for these examples can be found via the Tutorial and Examples +link in the main Qt documentation. + + +Finding the Qt Examples and Demos launcher +========================================== + +On Windows: + +The launcher can be accessed via the Windows Start menu. Select the menu +entry entitled "Qt Examples and Demos" entry in the submenu containing +the Qt tools. + +On Mac OS X: + +For the binary distribution, the qtdemo executable is installed in the +/Developer/Applications/Qt directory. For the source distribution, it is +installed alongside the other Qt tools on the path specified when Qt is +configured. + +On Unix/Linux: + +The qtdemo executable is installed alongside the other Qt tools on the path +specified when Qt is configured. + +On all platforms: + +The source code for the launcher can be found in the demos/qtdemo directory +in the Qt package. This example is built at the same time as the Qt libraries, +tools, examples, and demonstrations. -- cgit v0.12 From 5504a102e9f608fed7377332b8de7b823cf22b85 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 14:05:47 +0200 Subject: compile when using qt namespace --- src/3rdparty/easing/easing.cpp | 1 + src/corelib/tools/qeasingcurve.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/easing/easing.cpp b/src/3rdparty/easing/easing.cpp index 5bd3997..81af40f 100644 --- a/src/3rdparty/easing/easing.cpp +++ b/src/3rdparty/easing/easing.cpp @@ -26,6 +26,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #define M_PI_2 (M_PI / 2) #endif +QT_USE_NAMESPACE /** * Easing equation function for a simple linear tweening, with no easing. diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 34765c8..8c37137 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -295,6 +295,11 @@ #include "qeasingcurve.h" +#ifndef QT_NO_DEBUG_STREAM +#include +#include +#endif + QT_BEGIN_NAMESPACE static bool isConfigFunction(QEasingCurve::Type type) @@ -341,7 +346,9 @@ bool QEasingCurveFunction::operator==(const QEasingCurveFunction& other) _o == other._o; } +QT_BEGIN_INCLUDE_NAMESPACE #include "../3rdparty/easing/easing.cpp" +QT_END_INCLUDE_NAMESPACE class QEasingCurvePrivate { @@ -823,8 +830,6 @@ qreal QEasingCurve::valueForProgress(qreal progress) const } #ifndef QT_NO_DEBUG_STREAM -#include -#include QDebug operator<<(QDebug debug, const QEasingCurve &item) { debug << "type:" << item.d_ptr->type -- cgit v0.12 From ac5fceafb00a2f007239f9b0fc89fe01a2064d62 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 15:34:11 +0200 Subject: compile with -qtnamespace, clean up the example .pro files --- examples/animation/animatedtiles/animatedtiles.pro | 10 ++++++-- examples/animation/animatedtiles/main.cpp | 2 ++ examples/animation/appchooser/appchooser.pro | 5 ++-- examples/animation/easing/easing.pro | 24 ++++++++--------- examples/animation/easing/easing.qrc | 5 ++++ examples/animation/easing/main.cpp | 1 + examples/animation/easing/resources.qrc | 5 ---- examples/animation/moveblocks/moveblocks.pro | 5 ++-- .../animation/padnavigator-ng/padnavigator.pro | 12 ++++----- examples/animation/padnavigator-ng/panel.h | 4 +-- .../animation/padnavigator-ng/roundrectitem.cpp | 4 +-- examples/animation/stickman/animation.h | 2 ++ .../animation/stickman/editor/animationdialog.h | 2 ++ examples/animation/stickman/lifecycle.h | 2 ++ examples/animation/stickman/stickman.h | 2 ++ examples/animation/stickman/stickman.pro | 27 +++++++++++-------- examples/animation/sub-attaq/animationmanager.h | 2 ++ examples/animation/sub-attaq/boat.h | 2 ++ .../sub-attaq/custompropertyanimation.cpp | 7 ----- .../animation/sub-attaq/custompropertyanimation.h | 2 ++ examples/animation/sub-attaq/graphicsscene.h | 2 ++ examples/animation/sub-attaq/mainwindow.h | 3 ++- examples/animation/sub-attaq/states.h | 2 ++ examples/animation/sub-attaq/sub-attaq.pro | 15 +++++------ .../eventtransitions/eventtransitions.pro | 12 ++++----- examples/statemachine/factorial/factorial.pro | 11 ++++---- examples/statemachine/pingpong/pingpong.pro | 13 +++++----- examples/statemachine/tankgame/gameitem.h | 2 ++ examples/statemachine/tankgame/mainwindow.h | 3 +++ examples/statemachine/tankgame/plugin.h | 4 +++ examples/statemachine/tankgame/tankgame.pro | 30 +++++++++++++--------- .../statemachine/trafficlight/trafficlight.pro | 7 +---- .../statemachine/twowaybutton/twowaybutton.pro | 12 ++++----- 33 files changed, 136 insertions(+), 105 deletions(-) create mode 100644 examples/animation/easing/easing.qrc delete mode 100644 examples/animation/easing/resources.qrc diff --git a/examples/animation/animatedtiles/animatedtiles.pro b/examples/animation/animatedtiles/animatedtiles.pro index 9e9062c..1840b17 100644 --- a/examples/animation/animatedtiles/animatedtiles.pro +++ b/examples/animation/animatedtiles/animatedtiles.pro @@ -1,2 +1,8 @@ -SOURCES += main.cpp -RESOURCES += animatedtiles.qrc +SOURCES = main.cpp +RESOURCES = animatedtiles.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/animatedtiles +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS animatedtiles.pro images +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/animatedtiles +INSTALLS += target sources diff --git a/examples/animation/animatedtiles/main.cpp b/examples/animation/animatedtiles/main.cpp index 7988758..4b1d99d 100644 --- a/examples/animation/animatedtiles/main.cpp +++ b/examples/animation/animatedtiles/main.cpp @@ -132,6 +132,8 @@ protected: int main(int argc, char **argv) { + Q_INIT_RESOURCE(animatedtiles); + QApplication app(argc, argv); QPixmap kineticPix(":/images/kinetic.png"); diff --git a/examples/animation/appchooser/appchooser.pro b/examples/animation/appchooser/appchooser.pro index 8cda19a..847b60a 100644 --- a/examples/animation/appchooser/appchooser.pro +++ b/examples/animation/appchooser/appchooser.pro @@ -1,6 +1,5 @@ -# Input -SOURCES += main.cpp -RESOURCES += appchooser.qrc +SOURCES = main.cpp +RESOURCES = appchooser.qrc # install target.path = $$[QT_INSTALL_EXAMPLES]/animation/appchooser diff --git a/examples/animation/easing/easing.pro b/examples/animation/easing/easing.pro index fa5b22d..8e8a35f 100644 --- a/examples/animation/easing/easing.pro +++ b/examples/animation/easing/easing.pro @@ -1,16 +1,14 @@ -###################################################################### -# Automatically generated by qmake (2.01a) to 2. okt 23:22:11 2008 -###################################################################### +HEADERS = window.h \ + animation.h +SOURCES = main.cpp \ + window.cpp -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . +FORMS = form.ui -# Input -HEADERS += window.h animation.h -SOURCES += main.cpp window.cpp +RESOURCES = easing.qrc -FORMS += form.ui - -RESOURCES = resources.qrc +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/easing +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS easing.pro images +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/easing +INSTALLS += target sources diff --git a/examples/animation/easing/easing.qrc b/examples/animation/easing/easing.qrc new file mode 100644 index 0000000..7e112d3 --- /dev/null +++ b/examples/animation/easing/easing.qrc @@ -0,0 +1,5 @@ + + + images/qt-logo.png + + \ No newline at end of file diff --git a/examples/animation/easing/main.cpp b/examples/animation/easing/main.cpp index 487fa86..bd10df2 100644 --- a/examples/animation/easing/main.cpp +++ b/examples/animation/easing/main.cpp @@ -44,6 +44,7 @@ int main(int argc, char **argv) { + Q_INIT_RESOURCE(easing); QApplication app(argc, argv); Window w; w.resize(400, 400); diff --git a/examples/animation/easing/resources.qrc b/examples/animation/easing/resources.qrc deleted file mode 100644 index 7e112d3..0000000 --- a/examples/animation/easing/resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - images/qt-logo.png - - \ No newline at end of file diff --git a/examples/animation/moveblocks/moveblocks.pro b/examples/animation/moveblocks/moveblocks.pro index 7a82ca5..b8e88b2 100644 --- a/examples/animation/moveblocks/moveblocks.pro +++ b/examples/animation/moveblocks/moveblocks.pro @@ -1,8 +1,7 @@ -# Input -SOURCES += main.cpp +SOURCES = main.cpp # install target.path = $$[QT_INSTALL_EXAMPLES]/animation/moveblocks -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS states.pro +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS moveblocks.pro sources.path = $$[QT_INSTALL_EXAMPLES]/animation/moveblocks INSTALLS += target sources diff --git a/examples/animation/padnavigator-ng/padnavigator.pro b/examples/animation/padnavigator-ng/padnavigator.pro index 0d094c6..8e53a6d 100644 --- a/examples/animation/padnavigator-ng/padnavigator.pro +++ b/examples/animation/padnavigator-ng/padnavigator.pro @@ -1,24 +1,24 @@ -HEADERS += \ +HEADERS = \ panel.h \ roundrectitem.h \ splashitem.h -SOURCES += \ +SOURCES = \ panel.cpp \ roundrectitem.cpp \ splashitem.cpp \ main.cpp -RESOURCES += \ +RESOURCES = \ padnavigator.qrc -FORMS += \ +FORMS = \ backside.ui contains(QT_CONFIG, opengl):QT += opengl # install -target.path = $$[QT_INSTALL_EXAMPLES]/graphicsview/padnavigator +target.path = $$[QT_INSTALL_EXAMPLES]/animation/padnavigator-ng sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS padnavigator.pro images -sources.path = $$[QT_INSTALL_EXAMPLES]/graphicsview/padnavigator +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/padnavigator-ng INSTALLS += target sources diff --git a/examples/animation/padnavigator-ng/panel.h b/examples/animation/padnavigator-ng/panel.h index 8ad95d9..9aca29d 100644 --- a/examples/animation/padnavigator-ng/panel.h +++ b/examples/animation/padnavigator-ng/panel.h @@ -44,11 +44,11 @@ QT_BEGIN_NAMESPACE class Ui_BackSide; +class QAnimationGroup; +class QPropertyAnimation; QT_END_NAMESPACE; class RoundRectItem; -class QAnimationGroup; -class QPropertyAnimation; class Panel : public QGraphicsView { diff --git a/examples/animation/padnavigator-ng/roundrectitem.cpp b/examples/animation/padnavigator-ng/roundrectitem.cpp index 7e7d423..2ff216c 100644 --- a/examples/animation/padnavigator-ng/roundrectitem.cpp +++ b/examples/animation/padnavigator-ng/roundrectitem.cpp @@ -45,9 +45,9 @@ RoundRectItem::RoundRectItem(const QRectF &rect, const QBrush &brush, QWidget *embeddedWidget) : QGraphicsWidget(), + m_rect(rect), brush(brush), - proxyWidget(0), - m_rect(rect) + proxyWidget(0) { if (embeddedWidget) { proxyWidget = new QGraphicsProxyWidget(this); diff --git a/examples/animation/stickman/animation.h b/examples/animation/stickman/animation.h index e6c375e..b0b39c9 100644 --- a/examples/animation/stickman/animation.h +++ b/examples/animation/stickman/animation.h @@ -47,7 +47,9 @@ #include class Frame; +QT_BEGIN_NAMESPACE class QIODevice; +QT_END_NAMESPACE class Animation { public: diff --git a/examples/animation/stickman/editor/animationdialog.h b/examples/animation/stickman/editor/animationdialog.h index 764cdaf..6025088 100644 --- a/examples/animation/stickman/editor/animationdialog.h +++ b/examples/animation/stickman/editor/animationdialog.h @@ -45,8 +45,10 @@ #include #include +QT_BEGIN_NAMESPACE class QSpinBox; class QLineEdit; +QT_END_NAMESPACE class StickMan; class Animation; class AnimationDialog: public QDialog diff --git a/examples/animation/stickman/lifecycle.h b/examples/animation/stickman/lifecycle.h index 8fd0fb2..2be4762 100644 --- a/examples/animation/stickman/lifecycle.h +++ b/examples/animation/stickman/lifecycle.h @@ -45,11 +45,13 @@ #include class StickMan; +QT_BEGIN_NAMESPACE class QStateMachine; class QAnimationGroup; class QState; class QAbstractState; class QAbstractTransition; +QT_END_NAMESPACE class GraphicsView; class LifeCycle { diff --git a/examples/animation/stickman/stickman.h b/examples/animation/stickman/stickman.h index 46863a3..6395272 100644 --- a/examples/animation/stickman/stickman.h +++ b/examples/animation/stickman/stickman.h @@ -47,7 +47,9 @@ const int LimbCount = 16; class Node; +QT_BEGIN_NAMESPACE class QTimer; +QT_END_NAMESPACE class StickMan: public QObject, public QGraphicsItem { Q_OBJECT diff --git a/examples/animation/stickman/stickman.pro b/examples/animation/stickman/stickman.pro index bfee5b0..956b49c 100644 --- a/examples/animation/stickman/stickman.pro +++ b/examples/animation/stickman/stickman.pro @@ -1,14 +1,19 @@ -###################################################################### -# Automatically generated by qmake (2.01a) ti 3. feb 19:50:14 2009 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . +HEADERS += stickman.h \ + animation.h \ + node.h \ + lifecycle.h \ + graphicsview.h +SOURCES += main.cpp \ + stickman.cpp \ + animation.cpp \ + node.cpp \ + lifecycle.cpp \ + graphicsview.cpp include(editor/editor.pri) -# Input -HEADERS += stickman.h animation.h node.h lifecycle.h graphicsview.h -SOURCES += main.cpp stickman.cpp animation.cpp node.cpp lifecycle.cpp graphicsview.cpp +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/stickman +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS stickman.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/stickman +INSTALLS += target sources diff --git a/examples/animation/sub-attaq/animationmanager.h b/examples/animation/sub-attaq/animationmanager.h index 69ec3d7..a563c96 100644 --- a/examples/animation/sub-attaq/animationmanager.h +++ b/examples/animation/sub-attaq/animationmanager.h @@ -44,7 +44,9 @@ #include +QT_BEGIN_NAMESPACE class QAbstractAnimation; +QT_END_NAMESPACE class AnimationManager : public QObject { diff --git a/examples/animation/sub-attaq/boat.h b/examples/animation/sub-attaq/boat.h index f16074e..08a9fa2 100644 --- a/examples/animation/sub-attaq/boat.h +++ b/examples/animation/sub-attaq/boat.h @@ -50,9 +50,11 @@ class PixmapItem; class Bomb; +QT_BEGIN_NAMESPACE class QVariantAnimation; class QAbstractAnimation; class QStateMachine; +QT_END_NAMESPACE class Boat : public QGraphicsWidget { diff --git a/examples/animation/sub-attaq/custompropertyanimation.cpp b/examples/animation/sub-attaq/custompropertyanimation.cpp index f7ab269..8226cca 100644 --- a/examples/animation/sub-attaq/custompropertyanimation.cpp +++ b/examples/animation/sub-attaq/custompropertyanimation.cpp @@ -44,9 +44,6 @@ // Qt #include -QT_BEGIN_NAMESPACE - - CustomPropertyAnimation::CustomPropertyAnimation(QObject *parent) : QVariantAnimation(parent), animProp(0) { @@ -108,8 +105,4 @@ void CustomPropertyAnimation::updateState(QAbstractAnimation::State oldState, QA QVariantAnimation::updateState(oldState, newState); } - - #include "moc_custompropertyanimation.cpp" - -QT_END_NAMESPACE diff --git a/examples/animation/sub-attaq/custompropertyanimation.h b/examples/animation/sub-attaq/custompropertyanimation.h index 1dca454..8654aeb 100644 --- a/examples/animation/sub-attaq/custompropertyanimation.h +++ b/examples/animation/sub-attaq/custompropertyanimation.h @@ -44,7 +44,9 @@ #include +QT_BEGIN_NAMESPACE class QGraphicsItem; +QT_END_NAMESPACE struct AbstractProperty { diff --git a/examples/animation/sub-attaq/graphicsscene.h b/examples/animation/sub-attaq/graphicsscene.h index 70c873e..8b0ea96 100644 --- a/examples/animation/sub-attaq/graphicsscene.h +++ b/examples/animation/sub-attaq/graphicsscene.h @@ -54,7 +54,9 @@ class Torpedo; class Bomb; class PixmapItem; class ProgressItem; +QT_BEGIN_NAMESPACE class QAction; +QT_END_NAMESPACE class GraphicsScene : public QGraphicsScene { diff --git a/examples/animation/sub-attaq/mainwindow.h b/examples/animation/sub-attaq/mainwindow.h index 72d1324..87f194a 100644 --- a/examples/animation/sub-attaq/mainwindow.h +++ b/examples/animation/sub-attaq/mainwindow.h @@ -44,9 +44,10 @@ //Qt #include - class GraphicsScene; +QT_BEGIN_NAMESPACE class QGraphicsView; +QT_END_NAMESPACE class MainWindow : public QMainWindow { diff --git a/examples/animation/sub-attaq/states.h b/examples/animation/sub-attaq/states.h index 3203b3b..71375e0 100644 --- a/examples/animation/sub-attaq/states.h +++ b/examples/animation/sub-attaq/states.h @@ -52,7 +52,9 @@ class GraphicsScene; class Boat; class SubMarine; +QT_BEGIN_NAMESPACE class QStateMachine; +QT_END_NAMESPACE class PlayState : public QState { diff --git a/examples/animation/sub-attaq/sub-attaq.pro b/examples/animation/sub-attaq/sub-attaq.pro index 961a9b5..d13a099 100644 --- a/examples/animation/sub-attaq/sub-attaq.pro +++ b/examples/animation/sub-attaq/sub-attaq.pro @@ -1,14 +1,5 @@ -# ##################################################################### -# Automatically generated by qmake (2.01a) Thu Oct 9 10:53:30 2008 -# ##################################################################### -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . -QT += xml contains(QT_CONFIG, opengl):QT += opengl -# Input HEADERS += boat.h \ bomb.h \ mainwindow.h \ @@ -37,3 +28,9 @@ SOURCES += boat.cpp \ qanimationstate.cpp \ progressitem.cpp RESOURCES += subattaq.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/sub-attaq +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS sub-attaq.pro pics +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/sub-attaq +INSTALLS += target sources diff --git a/examples/statemachine/eventtransitions/eventtransitions.pro b/examples/statemachine/eventtransitions/eventtransitions.pro index 6a976cb..7e92cf2 100644 --- a/examples/statemachine/eventtransitions/eventtransitions.pro +++ b/examples/statemachine/eventtransitions/eventtransitions.pro @@ -1,7 +1,7 @@ -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . +SOURCES = main.cpp -# Input -SOURCES += main.cpp +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/eventtransitions +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS eventtransitions.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/eventtransitions +INSTALLS += target sources diff --git a/examples/statemachine/factorial/factorial.pro b/examples/statemachine/factorial/factorial.pro index ac79117..14a6833 100644 --- a/examples/statemachine/factorial/factorial.pro +++ b/examples/statemachine/factorial/factorial.pro @@ -1,10 +1,11 @@ -TEMPLATE = app -TARGET = QT = core win32: CONFIG += console mac:CONFIG -= app_bundle -DEPENDPATH += . -INCLUDEPATH += . -# Input SOURCES += main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/factorial +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS factorial.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/factorial +INSTALLS += target sources diff --git a/examples/statemachine/pingpong/pingpong.pro b/examples/statemachine/pingpong/pingpong.pro index bff9cb8..42eab6c 100644 --- a/examples/statemachine/pingpong/pingpong.pro +++ b/examples/statemachine/pingpong/pingpong.pro @@ -1,10 +1,11 @@ QT = core -TEMPLATE = app -TARGET = win32: CONFIG += console mac:CONFIG -= app_bundle -DEPENDPATH += . -INCLUDEPATH += . -# Input -SOURCES += main.cpp +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/pingpong +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS pingpong.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/pingpong +INSTALLS += target sources diff --git a/examples/statemachine/tankgame/gameitem.h b/examples/statemachine/tankgame/gameitem.h index 43b8785..33caf71 100644 --- a/examples/statemachine/tankgame/gameitem.h +++ b/examples/statemachine/tankgame/gameitem.h @@ -3,7 +3,9 @@ #include +QT_BEGIN_NAMESPACE class QLineF; +QT_END_NAMESPACE class GameItem: public QObject, public QGraphicsItem { Q_OBJECT diff --git a/examples/statemachine/tankgame/mainwindow.h b/examples/statemachine/tankgame/mainwindow.h index 40e1595..391ab77 100644 --- a/examples/statemachine/tankgame/mainwindow.h +++ b/examples/statemachine/tankgame/mainwindow.h @@ -4,11 +4,14 @@ #include #include +QT_BEGIN_NAMESPACE class QGraphicsScene; class QStateMachine; class QState; +QT_END_NAMESPACE class GameOverTransition; class TankItem; + class MainWindow: public QMainWindow { Q_OBJECT diff --git a/examples/statemachine/tankgame/plugin.h b/examples/statemachine/tankgame/plugin.h index 2b48d43..006ad78 100644 --- a/examples/statemachine/tankgame/plugin.h +++ b/examples/statemachine/tankgame/plugin.h @@ -3,7 +3,9 @@ #include +QT_BEGIN_NAMESPACE class QState; +QT_END_NAMESPACE class Plugin { public: @@ -12,6 +14,8 @@ public: virtual QState *create(QState *parentState, QObject *tank) = 0; }; +QT_BEGIN_NAMESPACE Q_DECLARE_INTERFACE(Plugin, "TankPlugin") +QT_END_NAMESPACE #endif diff --git a/examples/statemachine/tankgame/tankgame.pro b/examples/statemachine/tankgame/tankgame.pro index 46cfe2e..59415be 100644 --- a/examples/statemachine/tankgame/tankgame.pro +++ b/examples/statemachine/tankgame/tankgame.pro @@ -1,13 +1,19 @@ -###################################################################### -# Automatically generated by qmake (2.01a) on 22. apr 14:11:33 2009 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += C:/dev/kinetic/examples/statemachine/tankgame/. . - -# Input -HEADERS += mainwindow.h plugin.h tankitem.h rocketitem.h gameitem.h gameovertransition.h -SOURCES += main.cpp mainwindow.cpp tankitem.cpp rocketitem.cpp gameitem.cpp gameovertransition.cpp +HEADERS += mainwindow.h \ + plugin.h \ + tankitem.h \ + rocketitem.h \ + gameitem.h \ + gameovertransition.h +SOURCES += main.cpp \ + mainwindow.cpp \ + tankitem.cpp \ + rocketitem.cpp \ + gameitem.cpp \ + gameovertransition.cpp CONFIG += console + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS tankgame.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame +INSTALLS += target sources diff --git a/examples/statemachine/trafficlight/trafficlight.pro b/examples/statemachine/trafficlight/trafficlight.pro index 730bd75..684575a 100644 --- a/examples/statemachine/trafficlight/trafficlight.pro +++ b/examples/statemachine/trafficlight/trafficlight.pro @@ -1,9 +1,4 @@ -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -SOURCES += main.cpp +SOURCES = main.cpp # install target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/trafficlight diff --git a/examples/statemachine/twowaybutton/twowaybutton.pro b/examples/statemachine/twowaybutton/twowaybutton.pro index 6a976cb..f6cbc57 100644 --- a/examples/statemachine/twowaybutton/twowaybutton.pro +++ b/examples/statemachine/twowaybutton/twowaybutton.pro @@ -1,7 +1,7 @@ -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . +SOURCES = main.cpp -# Input -SOURCES += main.cpp +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/twowaybutton +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS twowaybutton.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/twowaybutton +INSTALLS += target sources -- cgit v0.12 From 5a60fd1a0b39b9d366a524cc8c8576b417551e6d Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 16:08:54 +0200 Subject: fix two .pro file bugs --- examples/animation/animation.pro | 1 - examples/examples.pro | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/animation/animation.pro b/examples/animation/animation.pro index 0a57d3d..d51a89d 100644 --- a/examples/animation/animation.pro +++ b/examples/animation/animation.pro @@ -4,7 +4,6 @@ SUBDIRS += \ animatedtiles \ appchooser \ easing \ - example \ moveblocks \ padnavigator-ng \ states \ diff --git a/examples/examples.pro b/examples/examples.pro index 332a712..bfcf9b4 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs SUBDIRS = \ + animation \ desktop \ dialogs \ draganddrop \ @@ -25,7 +26,6 @@ SUBDIRS = \ contains(QT_CONFIG, phonon):!static: SUBDIRS += phonon contains(QT_CONFIG, webkit): SUBDIRS += webkit -contains(QT_CONFIG, animation): SUBDIRS += animation embedded:SUBDIRS += qws !wince*: { !contains(QT_EDITION, Console):contains(QT_BUILD_PARTS, tools):SUBDIRS += designer -- cgit v0.12 From dcdd15156595dbc317732970e48efa32d32b256a Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 16:13:00 +0200 Subject: fix compiler warnings --- examples/animation/stickman/node.cpp | 4 ++-- examples/animation/stickman/stickman.cpp | 2 +- examples/statemachine/tankgame/mainwindow.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/animation/stickman/node.cpp b/examples/animation/stickman/node.cpp index ed18108..9c485d9 100644 --- a/examples/animation/stickman/node.cpp +++ b/examples/animation/stickman/node.cpp @@ -75,7 +75,7 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) return QGraphicsItem::itemChange(change, value); } -void Node::mousePressEvent(QGraphicsSceneMouseEvent *event) +void Node::mousePressEvent(QGraphicsSceneMouseEvent *) { m_dragging = true; } @@ -86,7 +86,7 @@ void Node::mouseMoveEvent(QGraphicsSceneMouseEvent *event) setPos(mapToParent(event->pos())); } -void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *) { m_dragging = false; } diff --git a/examples/animation/stickman/stickman.cpp b/examples/animation/stickman/stickman.cpp index 5eb392f..e00ea41 100644 --- a/examples/animation/stickman/stickman.cpp +++ b/examples/animation/stickman/stickman.cpp @@ -178,7 +178,7 @@ Node *StickMan::node(int idx) const return 0; } -void StickMan::timerEvent(QTimerEvent *e) +void StickMan::timerEvent(QTimerEvent *) { update(); } diff --git a/examples/statemachine/tankgame/mainwindow.cpp b/examples/statemachine/tankgame/mainwindow.cpp index fcc0325..3437140 100644 --- a/examples/statemachine/tankgame/mainwindow.cpp +++ b/examples/statemachine/tankgame/mainwindow.cpp @@ -201,7 +201,7 @@ void MainWindow::gameOver() TankItem *lastTankStanding = 0; foreach (QGraphicsItem *item, items) { if (GameItem *gameItem = qgraphicsitem_cast(item)) { - if (lastTankStanding = qobject_cast(gameItem)) + if ((lastTankStanding = qobject_cast(gameItem)) != 0) break; } } -- cgit v0.12 From bf69207bd98603bd645ba010f572c990fdb7d82b Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 20 May 2009 16:31:58 +0200 Subject: add animation and state machine examples to qtdemo --- demos/qtdemo/xml/examples.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/demos/qtdemo/xml/examples.xml b/demos/qtdemo/xml/examples.xml index 96a3e80..2560848 100644 --- a/demos/qtdemo/xml/examples.xml +++ b/demos/qtdemo/xml/examples.xml @@ -19,6 +19,15 @@ + + + + + + + + + @@ -167,6 +176,12 @@ + + + + + + -- cgit v0.12 From 8769a71f56886ea4925fc460a553f53500dd0b4e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 20 May 2009 15:59:52 +0200 Subject: Avoid memory leaks in QStateMachine tests Give some objects parents and allocate some objects on the stack to avoid leaking them. --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 57 +++++++++++++------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 7476831..d033869 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -522,8 +522,7 @@ void tst_QStateMachine::customLocalErrorStateInParentOfBrokenState() QState *parentOfBrokenState = new QState(); machine.addState(parentOfBrokenState); parentOfBrokenState->setObjectName("parentOfBrokenState"); - parentOfBrokenState->setErrorState(customErrorState); - + parentOfBrokenState->setErrorState(customErrorState); QState *brokenState = new QState(parentOfBrokenState); brokenState->setObjectName("brokenState"); @@ -891,7 +890,7 @@ void tst_QStateMachine::brokenStateIsNeverEntered() { QStateMachine machine; - QObject *entryController = new QObject(); + QObject *entryController = new QObject(&machine); entryController->setProperty("brokenStateEntered", false); entryController->setProperty("childStateEntered", false); entryController->setProperty("errorStateEntered", false); @@ -927,15 +926,15 @@ void tst_QStateMachine::transitionToStateNotInGraph() { s_countWarnings = false; - QStateMachine machine; + QStateMachine machine; QState *initialState = new QState(machine.rootState()); initialState->setObjectName("initialState"); machine.setInitialState(initialState); - QState *independentState = new QState(); - independentState->setObjectName("independentState"); - initialState->addTransition(independentState); + QState independentState; + independentState.setObjectName("independentState"); + initialState->addTransition(&independentState); machine.start(); QCoreApplication::processEvents(); @@ -950,10 +949,10 @@ void tst_QStateMachine::customErrorStateNotInGraph() QStateMachine machine; - QState *errorState = new QState(); - errorState->setObjectName("errorState"); - machine.setErrorState(errorState); - QVERIFY(errorState != machine.errorState()); + QState errorState; + errorState.setObjectName("errorState"); + machine.setErrorState(&errorState); + QVERIFY(&errorState != machine.errorState()); QState *initialBrokenState = new QState(machine.rootState()); initialBrokenState->setObjectName("initialBrokenState"); @@ -969,13 +968,13 @@ void tst_QStateMachine::customErrorStateNotInGraph() void tst_QStateMachine::restoreProperties() { - QObject *object = new QObject(); - object->setProperty("a", 1); - object->setProperty("b", 2); - QStateMachine machine; machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + QObject *object = new QObject(&machine); + object->setProperty("a", 1); + object->setProperty("b", 2); + QState *S1 = new QState(); S1->setObjectName("S1"); S1->assignProperty(object, "a", 3); @@ -2025,8 +2024,8 @@ void tst_QStateMachine::targetStateWithNoParent() QStateMachine machine; QState *s1 = new QState(machine.rootState()); s1->setObjectName("s1"); - QState *s2 = new QState(); - s1->addTransition(s2); + QState s2; + s1->addTransition(&s2); machine.setInitialState(s1); QSignalSpy startedSpy(&machine, SIGNAL(started())); QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); @@ -2058,7 +2057,7 @@ void tst_QStateMachine::defaultGlobalRestorePolicy() { QStateMachine machine; - QObject *propertyHolder = new QObject(); + QObject *propertyHolder = new QObject(&machine); propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); @@ -2147,7 +2146,7 @@ void tst_QStateMachine::globalRestorePolicySetToDoNotRestore() QStateMachine machine; machine.setGlobalRestorePolicy(QStateMachine::DoNotRestoreProperties); - QObject *propertyHolder = new QObject(); + QObject *propertyHolder = new QObject(&machine); propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); @@ -2308,7 +2307,7 @@ void tst_QStateMachine::globalRestorePolicySetToRestore() QStateMachine machine; machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - QObject *propertyHolder = new QObject(); + QObject *propertyHolder = new QObject(&machine); propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); @@ -2428,7 +2427,7 @@ void tst_QStateMachine::simpleAnimation() { QStateMachine machine; - QObject *object = new QObject(); + QObject *object = new QObject(&machine); object->setProperty("fooBar", 1.0); QState *s1 = new QState(machine.rootState()); @@ -2471,7 +2470,7 @@ void tst_QStateMachine::twoAnimations() { QStateMachine machine; - QObject *object = new QObject(); + QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); object->setProperty("bar", 3.0); @@ -2515,7 +2514,7 @@ void tst_QStateMachine::twoAnimatedTransitions() { QStateMachine machine; - QObject *object = new QObject(); + QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); QState *s1 = new QState(machine.rootState()); @@ -2559,7 +2558,7 @@ void tst_QStateMachine::playAnimationTwice() { QStateMachine machine; - QObject *object = new QObject(); + QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); QState *s1 = new QState(machine.rootState()); @@ -2602,7 +2601,7 @@ void tst_QStateMachine::nestedTargetStateForAnimation() { QStateMachine machine; - QObject *object = new QObject(); + QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); object->setProperty("bar", 3.0); @@ -2659,7 +2658,7 @@ void tst_QStateMachine::animatedGlobalRestoreProperty() QStateMachine machine; machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - QObject *object = new QObject(); + QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); SlotCalledCounter counter; @@ -2705,7 +2704,7 @@ void tst_QStateMachine::specificTargetValueOfAnimation() { QStateMachine machine; - QObject *object = new QObject(); + QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); QState *s1 = new QState(machine.rootState()); @@ -2769,7 +2768,7 @@ void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation() { QStateMachine machine; - QObject *object = new QObject(); + QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); object->setProperty("bar", 2.0); @@ -2848,7 +2847,7 @@ void tst_QStateMachine::overrideDefaultAnimationWithSpecific() { QStateMachine machine; - QObject *object = new QObject(); + QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); SlotCalledCounter counter; -- cgit v0.12 From b5fd79dfe69513ccf8d83e2eac45ae9b830a2d56 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 20 May 2009 08:38:32 +0200 Subject: Fix GLSL for OMAP3 and error checking --- src/opengl/gl2paintengineex/qglengineshadermanager.cpp | 4 ++-- src/opengl/gl2paintengineex/qglengineshadersource_p.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index d238830..514aac0 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -154,7 +154,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) simpleShaderProg->addShader(compiledShaders[MainFragmentShader]); simpleShaderProg->addShader(compiledShaders[ShockingPinkSrcFragmentShader]); simpleShaderProg->link(); - if (!simpleShaderProg->isValid()) { + if (!simpleShaderProg->isLinked()) { qCritical() << "Errors linking simple shader:" << simpleShaderProg->log(); } @@ -418,7 +418,7 @@ bool QGLEngineShaderManager::useCorrectShaderProg() requiredProgram.program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); requiredProgram.program->link(); - if (!requiredProgram.program->isValid()) { + if (!requiredProgram.program->isLinked()) { QString error; qWarning() << "Shader program failed to link," #if defined(QT_DEBUG) diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index bf896b1..fdbba72 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -284,7 +284,7 @@ static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\ static const char* const qglslShockingPinkSrcFragmentShader = "\ lowp vec4 srcPixel() { \ - return lowp vec4(0.98, 0.06, 0.75, 1.0); \ + return vec4(0.98, 0.06, 0.75, 1.0); \ }"; -- cgit v0.12 From 27fadaa7eb2d58b47e7f0f508e3402e7a8de3894 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 20 May 2009 16:42:02 +0200 Subject: Make QEglProperties::value() return the EGL default if not set Previously it would always return EGL_DONT_CARE, which causes a bug somewhere on X11 leading to configs being requested with E.g. EGL_GREEN_SIZE == EGL_DONT_CARE == -1 == 0xFFFFFFFF when cast to a uint. This also helps debug config matching as toString() now indicates the match criteria EGL will use. --- src/opengl/qegl.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/opengl/qegl.cpp b/src/opengl/qegl.cpp index 165a0f3..aebc3cb 100644 --- a/src/opengl/qegl.cpp +++ b/src/opengl/qegl.cpp @@ -405,7 +405,54 @@ int QEglProperties::value(int name) const if (props[index] == name) return props[index + 1]; } - return EGL_DONT_CARE; + + // If the attribute has not been explicitly set, return the EGL default + // The following defaults were taken from the EGL 1.4 spec: + switch(name) { + case EGL_BUFFER_SIZE: return 0; + case EGL_RED_SIZE: return 0; + case EGL_GREEN_SIZE: return 0; + case EGL_BLUE_SIZE: return 0; + case EGL_LUMINANCE_SIZE: return 0; + case EGL_ALPHA_SIZE: return 0; + case EGL_ALPHA_MASK_SIZE: return 0; + case EGL_BIND_TO_TEXTURE_RGB: return EGL_DONT_CARE; + case EGL_BIND_TO_TEXTURE_RGBA: return EGL_DONT_CARE; + case EGL_COLOR_BUFFER_TYPE: return EGL_RGB_BUFFER; + case EGL_CONFIG_CAVEAT: return EGL_DONT_CARE; + case EGL_CONFIG_ID: return EGL_DONT_CARE; + case EGL_DEPTH_SIZE: return 0; + case EGL_LEVEL: return 0; + case EGL_NATIVE_RENDERABLE: return EGL_DONT_CARE; + case EGL_NATIVE_VISUAL_TYPE: return EGL_DONT_CARE; + case EGL_MAX_SWAP_INTERVAL: return EGL_DONT_CARE; + case EGL_MIN_SWAP_INTERVAL: return EGL_DONT_CARE; + case EGL_RENDERABLE_TYPE: return EGL_OPENGL_ES_BIT; + case EGL_SAMPLE_BUFFERS: return 0; + case EGL_SAMPLES: return 0; + case EGL_STENCIL_SIZE: return 0; + case EGL_SURFACE_TYPE: return EGL_WINDOW_BIT; + case EGL_TRANSPARENT_TYPE: return EGL_NONE; + case EGL_TRANSPARENT_RED_VALUE: return EGL_DONT_CARE; + case EGL_TRANSPARENT_GREEN_VALUE: return EGL_DONT_CARE; + case EGL_TRANSPARENT_BLUE_VALUE: return EGL_DONT_CARE; + +#if defined(EGL_VERSION_1_3) + case EGL_CONFORMANT: return 0; + case EGL_MATCH_NATIVE_PIXMAP: return EGL_NONE; +#endif + + case EGL_MAX_PBUFFER_HEIGHT: + case EGL_MAX_PBUFFER_WIDTH: + case EGL_MAX_PBUFFER_PIXELS: + case EGL_NATIVE_VISUAL_ID: + case EGL_NONE: + qWarning("QEglProperties::value() - Attibute %d does not affect config selection", name); + return 0; + default: + qWarning("QEglProperties::value() - Attibute %d is unknown in EGL <=1.4", name); + return EGL_DONT_CARE; + } } // Set the value associated with a property, replacing an existing -- cgit v0.12 From 1cad8c56002a61a6240e6580cdbd784209821fa6 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 20 May 2009 17:16:48 +0200 Subject: update the padnavigator example and suppress the padnavigator-ng --- examples/animation/padnavigator-ng/backside.ui | 208 ----------------- .../padnavigator-ng/images/artsfftscope.png | Bin 1294 -> 0 bytes .../padnavigator-ng/images/blue_angle_swirl.jpg | Bin 11826 -> 0 bytes .../padnavigator-ng/images/kontact_contacts.png | Bin 4382 -> 0 bytes .../padnavigator-ng/images/kontact_journal.png | Bin 3261 -> 0 bytes .../padnavigator-ng/images/kontact_mail.png | Bin 3202 -> 0 bytes .../padnavigator-ng/images/kontact_notes.png | Bin 3893 -> 0 bytes .../padnavigator-ng/images/kopeteavailable.png | Bin 2380 -> 0 bytes .../padnavigator-ng/images/metacontact_online.png | Bin 2545 -> 0 bytes .../animation/padnavigator-ng/images/minitools.png | Bin 2087 -> 0 bytes examples/animation/padnavigator-ng/main.cpp | 54 ----- .../animation/padnavigator-ng/padnavigator.pro | 24 -- .../animation/padnavigator-ng/padnavigator.qrc | 14 -- examples/animation/padnavigator-ng/panel.cpp | 246 --------------------- examples/animation/padnavigator-ng/panel.h | 85 ------- .../animation/padnavigator-ng/roundrectitem.cpp | 136 ------------ examples/animation/padnavigator-ng/roundrectitem.h | 73 ------ examples/animation/padnavigator-ng/splashitem.cpp | 85 ------- examples/animation/padnavigator-ng/splashitem.h | 57 ----- .../padnavigator/images/artsfftscope.png | Bin 1291 -> 1290 bytes examples/graphicsview/padnavigator/main.cpp | 4 - examples/graphicsview/padnavigator/panel.cpp | 168 +++++++------- examples/graphicsview/padnavigator/panel.h | 29 +-- .../graphicsview/padnavigator/roundrectitem.cpp | 114 ++++------ examples/graphicsview/padnavigator/roundrectitem.h | 16 +- examples/graphicsview/padnavigator/splashitem.cpp | 25 +-- examples/graphicsview/padnavigator/splashitem.h | 6 - 27 files changed, 154 insertions(+), 1190 deletions(-) delete mode 100644 examples/animation/padnavigator-ng/backside.ui delete mode 100644 examples/animation/padnavigator-ng/images/artsfftscope.png delete mode 100644 examples/animation/padnavigator-ng/images/blue_angle_swirl.jpg delete mode 100644 examples/animation/padnavigator-ng/images/kontact_contacts.png delete mode 100644 examples/animation/padnavigator-ng/images/kontact_journal.png delete mode 100644 examples/animation/padnavigator-ng/images/kontact_mail.png delete mode 100644 examples/animation/padnavigator-ng/images/kontact_notes.png delete mode 100644 examples/animation/padnavigator-ng/images/kopeteavailable.png delete mode 100644 examples/animation/padnavigator-ng/images/metacontact_online.png delete mode 100644 examples/animation/padnavigator-ng/images/minitools.png delete mode 100644 examples/animation/padnavigator-ng/main.cpp delete mode 100644 examples/animation/padnavigator-ng/padnavigator.pro delete mode 100644 examples/animation/padnavigator-ng/padnavigator.qrc delete mode 100644 examples/animation/padnavigator-ng/panel.cpp delete mode 100644 examples/animation/padnavigator-ng/panel.h delete mode 100644 examples/animation/padnavigator-ng/roundrectitem.cpp delete mode 100644 examples/animation/padnavigator-ng/roundrectitem.h delete mode 100644 examples/animation/padnavigator-ng/splashitem.cpp delete mode 100644 examples/animation/padnavigator-ng/splashitem.h diff --git a/examples/animation/padnavigator-ng/backside.ui b/examples/animation/padnavigator-ng/backside.ui deleted file mode 100644 index afa488c..0000000 --- a/examples/animation/padnavigator-ng/backside.ui +++ /dev/null @@ -1,208 +0,0 @@ - - BackSide - - - - 0 - 0 - 378 - 385 - - - - BackSide - - - - - - Settings - - - true - - - true - - - - - - Title: - - - - - - - Pad Navigator Example - - - - - - - Modified: - - - - - - - Extent - - - - - - - - - 42 - - - Qt::Horizontal - - - - - - - 42 - - - - - - - - - - - - - - - Other input - - - true - - - true - - - - - - - Widgets On Graphics View - - - - - QGraphicsProxyWidget - - - - QGraphicsWidget - - - - QObject - - - - - QGraphicsItem - - - - - QGraphicsLayoutItem - - - - - - - QGraphicsGridLayout - - - - QGraphicsLayout - - - - QGraphicsLayoutItem - - - - - - - QGraphicsLinearLayout - - - - QGraphicsLayout - - - - QGraphicsLayoutItem - - - - - - - - - - - - - groupBox - hostName - dateTimeEdit - horizontalSlider - spinBox - groupBox_2 - treeWidget - - - - - horizontalSlider - valueChanged(int) - spinBox - setValue(int) - - - 184 - 125 - - - 275 - 127 - - - - - spinBox - valueChanged(int) - horizontalSlider - setValue(int) - - - 272 - 114 - - - 190 - 126 - - - - - diff --git a/examples/animation/padnavigator-ng/images/artsfftscope.png b/examples/animation/padnavigator-ng/images/artsfftscope.png deleted file mode 100644 index b4b8775..0000000 Binary files a/examples/animation/padnavigator-ng/images/artsfftscope.png and /dev/null differ diff --git a/examples/animation/padnavigator-ng/images/blue_angle_swirl.jpg b/examples/animation/padnavigator-ng/images/blue_angle_swirl.jpg deleted file mode 100644 index 5bf0deb..0000000 Binary files a/examples/animation/padnavigator-ng/images/blue_angle_swirl.jpg and /dev/null differ diff --git a/examples/animation/padnavigator-ng/images/kontact_contacts.png b/examples/animation/padnavigator-ng/images/kontact_contacts.png deleted file mode 100644 index 6fb4cc8..0000000 Binary files a/examples/animation/padnavigator-ng/images/kontact_contacts.png and /dev/null differ diff --git a/examples/animation/padnavigator-ng/images/kontact_journal.png b/examples/animation/padnavigator-ng/images/kontact_journal.png deleted file mode 100644 index b1fedb6..0000000 Binary files a/examples/animation/padnavigator-ng/images/kontact_journal.png and /dev/null differ diff --git a/examples/animation/padnavigator-ng/images/kontact_mail.png b/examples/animation/padnavigator-ng/images/kontact_mail.png deleted file mode 100644 index 672f8fa..0000000 Binary files a/examples/animation/padnavigator-ng/images/kontact_mail.png and /dev/null differ diff --git a/examples/animation/padnavigator-ng/images/kontact_notes.png b/examples/animation/padnavigator-ng/images/kontact_notes.png deleted file mode 100644 index 229bf73..0000000 Binary files a/examples/animation/padnavigator-ng/images/kontact_notes.png and /dev/null differ diff --git a/examples/animation/padnavigator-ng/images/kopeteavailable.png b/examples/animation/padnavigator-ng/images/kopeteavailable.png deleted file mode 100644 index 2eaf41a..0000000 Binary files a/examples/animation/padnavigator-ng/images/kopeteavailable.png and /dev/null differ diff --git a/examples/animation/padnavigator-ng/images/metacontact_online.png b/examples/animation/padnavigator-ng/images/metacontact_online.png deleted file mode 100644 index 6a398dd..0000000 Binary files a/examples/animation/padnavigator-ng/images/metacontact_online.png and /dev/null differ diff --git a/examples/animation/padnavigator-ng/images/minitools.png b/examples/animation/padnavigator-ng/images/minitools.png deleted file mode 100644 index 0248c9d..0000000 Binary files a/examples/animation/padnavigator-ng/images/minitools.png and /dev/null differ diff --git a/examples/animation/padnavigator-ng/main.cpp b/examples/animation/padnavigator-ng/main.cpp deleted file mode 100644 index f8b167f..0000000 --- a/examples/animation/padnavigator-ng/main.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "panel.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - Q_INIT_RESOURCE(padnavigator); - - Panel panel(3, 3); - panel.show(); - - return app.exec(); -} diff --git a/examples/animation/padnavigator-ng/padnavigator.pro b/examples/animation/padnavigator-ng/padnavigator.pro deleted file mode 100644 index 8e53a6d..0000000 --- a/examples/animation/padnavigator-ng/padnavigator.pro +++ /dev/null @@ -1,24 +0,0 @@ -HEADERS = \ - panel.h \ - roundrectitem.h \ - splashitem.h - -SOURCES = \ - panel.cpp \ - roundrectitem.cpp \ - splashitem.cpp \ - main.cpp - -RESOURCES = \ - padnavigator.qrc - -FORMS = \ - backside.ui - -contains(QT_CONFIG, opengl):QT += opengl - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/animation/padnavigator-ng -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS padnavigator.pro images -sources.path = $$[QT_INSTALL_EXAMPLES]/animation/padnavigator-ng -INSTALLS += target sources diff --git a/examples/animation/padnavigator-ng/padnavigator.qrc b/examples/animation/padnavigator-ng/padnavigator.qrc deleted file mode 100644 index 30ee8e1..0000000 --- a/examples/animation/padnavigator-ng/padnavigator.qrc +++ /dev/null @@ -1,14 +0,0 @@ - - - images/blue_angle_swirl.jpg - images/artsfftscope.png - images/kontact_contacts.png - images/kontact_journal.png - images/kontact_mail.png - images/kontact_notes.png - images/kopeteavailable.png - images/metacontact_online.png - images/minitools.png - images/blue_angle_swirl.jpg - - diff --git a/examples/animation/padnavigator-ng/panel.cpp b/examples/animation/padnavigator-ng/panel.cpp deleted file mode 100644 index e61be0e..0000000 --- a/examples/animation/padnavigator-ng/panel.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "panel.h" -#include "roundrectitem.h" -#include "splashitem.h" -#include "ui_backside.h" - -#ifndef QT_NO_OPENGL -#include -#else -#endif -#include - -Panel::Panel(int width, int height) - : selectedIndex(0), - grid(width*height), - width(width), - height(height), - flipped(false), - flippingGroup(0), - rotationXanim(0), - rotationYanim(0) -{ - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setCacheMode(CacheBackground); - setViewportUpdateMode(FullViewportUpdate); - setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - setBackgroundBrush(QPixmap(":/images/blue_angle_swirl.jpg")); -#ifndef QT_NO_OPENGL - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); -#endif - - QRectF bounds((-width / 2.0) * 150, (-height / 2.0) * 150, width * 150, height * 150); - - setScene(new QGraphicsScene(bounds, this)); - - baseItem = new RoundRectItem(bounds, QColor(226, 255, 92, 64)); - scene()->addItem(baseItem); - - QWidget *embed = new QWidget; - ui = new Ui_BackSide; - ui->setupUi(embed); - ui->hostName->setFocus(); - - backItem = new RoundRectItem(bounds, embed->palette().window(), embed); - backItem->setYRotation(180); - backItem->setParentItem(baseItem); - - selectionItem = new RoundRectItem(QRectF(-60, -60, 120, 120), Qt::gray); - selectionItem->setParentItem(baseItem); - selectionItem->setZValue(-1); - selectionItem->setPos(posForLocation(0)); - - int currentIndex = 0; - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - RoundRectItem *item = new RoundRectItem(QRectF(-54, -54, 108, 108), - QColor(214, 240, 110, 128)); - item->setPos(posForLocation(currentIndex)); - - item->setParentItem(baseItem); - item->setFlag(QGraphicsItem::ItemIsFocusable); - grid[currentIndex++] = item; - - switch (qrand() % 9) { - case 0: item->setPixmap(QPixmap(":/images/kontact_contacts.png")); break; - case 1: item->setPixmap(QPixmap(":/images/kontact_journal.png")); break; - case 2: item->setPixmap(QPixmap(":/images/kontact_notes.png")); break; - case 3: item->setPixmap(QPixmap(":/images/kopeteavailable.png")); break; - case 4: item->setPixmap(QPixmap(":/images/metacontact_online.png")); break; - case 5: item->setPixmap(QPixmap(":/images/minitools.png")); break; - case 6: item->setPixmap(QPixmap(":/images/kontact_journal.png")); break; - case 7: item->setPixmap(QPixmap(":/images/kontact_contacts.png")); break; - case 8: item->setPixmap(QPixmap(":/images/kopeteavailable.png")); break; - default: - break; - } - - connect(item, SIGNAL(activated()), this, SLOT(flip())); - } - } - - grid.first()->setFocus(); - - connect(backItem, SIGNAL(activated()), - this, SLOT(flip())); - - splash = new SplashItem; - splash->setZValue(5); - splash->setPos(-splash->rect().width() / 2, scene()->sceneRect().top()); - scene()->addItem(splash); - - splash->grabKeyboard(); - - //initialize the position - baseItem->setYRotation(selectionItem->x()/6.); - baseItem->setXRotation(selectionItem->y()/6.); - - setWindowTitle(tr("Pad Navigator Example")); -} - -Panel::~Panel() -{ -} - -void Panel::keyPressEvent(QKeyEvent *event) -{ - if (splash->isVisible() || event->key() == Qt::Key_Return || flipped) { - QGraphicsView::keyPressEvent(event); - return; - } - - selectedIndex = (selectedIndex + grid.count() + (event->key() == Qt::Key_Right) - (event->key() == Qt::Key_Left) - + width * ((event->key() == Qt::Key_Down) - (event->key() == Qt::Key_Up))) % grid.count(); - grid[selectedIndex]->setFocus(); - - const QPointF pos = posForLocation(selectedIndex); - - const double angleY = pos.x() / 6., - angleX = pos.y() / 6.; - - QAnimationGroup *group = new QParallelAnimationGroup(); - - QVariantAnimation *anim = new QPropertyAnimation(baseItem, "xRotation"); - anim->setEndValue(angleX); - anim->setDuration(150); - anim->setEasingCurve(QEasingCurve::OutInSine); - group->addAnimation(anim); - - anim = new QPropertyAnimation(baseItem, "yRotation"); - anim->setEndValue(angleY); - anim->setDuration(150); - anim->setEasingCurve(QEasingCurve::OutInSine); - group->addAnimation(anim); - - anim = new QPropertyAnimation(selectionItem, "pos"); - anim->setEndValue(pos); - anim->setDuration(150); - anim->setEasingCurve(QEasingCurve::Linear); - group->addAnimation(anim); - - group->start(QAbstractAnimation::DeleteWhenStopped); -} - -void Panel::resizeEvent(QResizeEvent *event) -{ - QGraphicsView::resizeEvent(event); - fitInView(scene()->sceneRect(), Qt::KeepAspectRatio); -} - -void Panel::flip() -{ - grid[selectedIndex]->setFocus(); - - if (flippingGroup == 0) { - flippingGroup = new QParallelAnimationGroup(this); - - const qreal zoomOut = qreal(.75); - - //slight scaling down while flipping - QVariantAnimation *anim = new QPropertyAnimation(baseItem, "yScale"); - anim->setKeyValueAt(qreal(.5), zoomOut); - anim->setEndValue(1); - anim->setEasingCurve(QEasingCurve::OutInSine); - anim->setDuration(500); - flippingGroup->addAnimation(anim); - - anim = new QPropertyAnimation(baseItem, "xScale"); - anim->setKeyValueAt(qreal(.5), zoomOut); - anim->setEndValue(1); - anim->setEasingCurve(QEasingCurve::OutInSine); - anim->setDuration(500); - flippingGroup->addAnimation(anim); - - rotationXanim = new QPropertyAnimation(baseItem, "xRotation"); - rotationXanim->setEndValue(0); - rotationXanim->setDuration(500); - flippingGroup->addAnimation(rotationXanim); - - rotationYanim = new QPropertyAnimation(baseItem, "yRotation"); - rotationYanim->setEndValue(180); - rotationYanim->setDuration(500); - flippingGroup->addAnimation(rotationYanim); - } - - if (flippingGroup->currentTime() != 0 && flippingGroup->direction() == QAbstractAnimation::Forward) { - flippingGroup->setDirection(QAbstractAnimation::Backward); - } else { - flippingGroup->setDirection(QAbstractAnimation::Forward); - if (flippingGroup->currentTime() == 0) { - //we always make sure when it is at the beginning - rotationXanim->setStartValue(baseItem->xRotation()); - rotationYanim->setStartValue(baseItem->yRotation()); - } - } - flippingGroup->start(); - flipped = !flipped; -} - -QPointF Panel::posForLocation(int index) const -{ - const int x = index % width, - y = index / width; - return QPointF(x * 150, y * 150) - - QPointF((width - 1) * 75, (height - 1) * 75); -} diff --git a/examples/animation/padnavigator-ng/panel.h b/examples/animation/padnavigator-ng/panel.h deleted file mode 100644 index 9aca29d..0000000 --- a/examples/animation/padnavigator-ng/panel.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -QT_BEGIN_NAMESPACE -class Ui_BackSide; -class QAnimationGroup; -class QPropertyAnimation; -QT_END_NAMESPACE; - -class RoundRectItem; - -class Panel : public QGraphicsView -{ - Q_OBJECT -public: - Panel(int width, int height); - ~Panel(); - -protected: - void keyPressEvent(QKeyEvent *event); - void resizeEvent(QResizeEvent *event); - -private Q_SLOTS: - void flip(); - -private: - QPointF posForLocation(int index) const; - - QGraphicsWidget *selectionItem; - QGraphicsWidget *baseItem; - RoundRectItem *backItem; - QGraphicsWidget *splash; - int selectedIndex; - - QVector grid; - - int width; - int height; - bool flipped; - Ui_BackSide *ui; - - QAnimationGroup *flippingGroup; - QPropertyAnimation *rotationXanim, *rotationYanim; -}; diff --git a/examples/animation/padnavigator-ng/roundrectitem.cpp b/examples/animation/padnavigator-ng/roundrectitem.cpp deleted file mode 100644 index 2ff216c..0000000 --- a/examples/animation/padnavigator-ng/roundrectitem.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "roundrectitem.h" - -#include - -RoundRectItem::RoundRectItem(const QRectF &rect, const QBrush &brush, QWidget *embeddedWidget) - : QGraphicsWidget(), - m_rect(rect), - brush(brush), - proxyWidget(0) -{ - if (embeddedWidget) { - proxyWidget = new QGraphicsProxyWidget(this); - proxyWidget->setFocusPolicy(Qt::StrongFocus); - proxyWidget->setWidget(embeddedWidget); - } -} - -void RoundRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - const bool widgetHidden = parentItem() == 0 || qAbs(static_cast(parentItem())->yRotation()) < 90; - - if (proxyWidget) { - if (widgetHidden) { - proxyWidget->hide(); - } else { - if (!proxyWidget->isVisible()) { - proxyWidget->setGeometry(boundingRect().adjusted(25, 25, -25, -25)); - proxyWidget->show(); - proxyWidget->setFocus(); - } - painter->setBrush(brush); - painter->setPen(QPen(Qt::black, 1)); - painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - painter->drawRoundRect(m_rect); - } - } else if (widgetHidden) { - painter->setPen(Qt::NoPen); - painter->setBrush(QColor(0, 0, 0, 64)); - painter->drawRoundRect(m_rect.translated(2, 2)); - - QLinearGradient gradient(m_rect.topLeft(), m_rect.bottomRight()); - const QColor col = brush.color(); - gradient.setColorAt(0, col); - gradient.setColorAt(1, col.dark(200)); - painter->setBrush(gradient); - painter->setPen(QPen(Qt::black, 1)); - painter->drawRoundRect(m_rect); - if (!pix.isNull()) { - painter->scale(qreal(1.95), qreal(1.95)); - painter->drawPixmap(-pix.width() / 2, -pix.height() / 2, pix); - } - } - -} - -QRectF RoundRectItem::boundingRect() const -{ - qreal penW = qreal(.5); - qreal shadowW = 2; - return m_rect.adjusted(-penW, -penW, penW + shadowW, penW + shadowW); -} - -void RoundRectItem::setPixmap(const QPixmap &pixmap) -{ - pix = pixmap; - if (scene() && isVisible()) - update(); -} - -void RoundRectItem::keyPressEvent(QKeyEvent *event) -{ - if (event->isAutoRepeat() || event->key() != Qt::Key_Return) { - QGraphicsWidget::keyPressEvent(event); - return; - } - - if (!proxyWidget) { - setXScale(qreal(.9)); - setYScale(qreal(.9)); - } - emit activated(); -} - -void RoundRectItem::keyReleaseEvent(QKeyEvent *event) -{ - if (event->isAutoRepeat() || event->key() != Qt::Key_Return) { - QGraphicsWidget::keyReleaseEvent(event); - return; - } - - if (!proxyWidget) { - setXScale(1); - setYScale(1); - } -} diff --git a/examples/animation/padnavigator-ng/roundrectitem.h b/examples/animation/padnavigator-ng/roundrectitem.h deleted file mode 100644 index 6a7bf4b..0000000 --- a/examples/animation/padnavigator-ng/roundrectitem.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QGraphicsProxyWidget; -QT_END_NAMESPACE; - -class RoundRectItem : public QGraphicsWidget -{ - Q_OBJECT -public: - RoundRectItem(const QRectF &rect, const QBrush &brush, QWidget *embeddedWidget = 0); - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); - QRectF boundingRect() const; - - void setPixmap(const QPixmap &pixmap); - -Q_SIGNALS: - void activated(); - -protected: - void keyPressEvent(QKeyEvent *event); - void keyReleaseEvent(QKeyEvent *event); - -private: - QRectF m_rect; - QBrush brush; - QPixmap pix; - QGraphicsProxyWidget *proxyWidget; -}; diff --git a/examples/animation/padnavigator-ng/splashitem.cpp b/examples/animation/padnavigator-ng/splashitem.cpp deleted file mode 100644 index 1264987..0000000 --- a/examples/animation/padnavigator-ng/splashitem.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "splashitem.h" - -#include - -SplashItem::SplashItem(QGraphicsItem *parent) - : QGraphicsWidget(parent) -{ - - text = tr("Welcome to the Pad Navigator Example. You can use the" - " keyboard arrows to navigate the icons, and press enter" - " to activate an item. Please press any key to continue."); - resize(400, 175); -} - -void SplashItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - painter->setPen(QPen(Qt::black, 2)); - painter->setBrush(QColor(245, 245, 255, 220)); - painter->setClipRect(rect()); - painter->drawRoundRect(3, -100 + 3, 400 - 6, 250 - 6); - - QRectF textRect = rect().adjusted(10, 10, -10, -10); - int flags = Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap; - - QFont font; - font.setPixelSize(18); - painter->setPen(Qt::black); - painter->setFont(font); - painter->drawText(textRect, flags, text); -} - -void SplashItem::keyPressEvent(QKeyEvent * /* event */) -{ - QVariantAnimation *anim = new QPropertyAnimation(this, "pos"); - anim->setEndValue(QPointF(x(), scene()->sceneRect().top() - rect().height())); - anim->setDuration(350); - anim->start(QAbstractAnimation::DeleteWhenStopped); - - anim = new QPropertyAnimation(this, "opacity"); - anim->setEndValue(0); - anim->start(QAbstractAnimation::DeleteWhenStopped); - - connect(anim, SIGNAL(finished()), SLOT(close())); -} diff --git a/examples/animation/padnavigator-ng/splashitem.h b/examples/animation/padnavigator-ng/splashitem.h deleted file mode 100644 index 7b4b8a9..0000000 --- a/examples/animation/padnavigator-ng/splashitem.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -class SplashItem : public QGraphicsWidget -{ - Q_OBJECT -public: - SplashItem(QGraphicsItem *parent = 0); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - -protected: - void keyPressEvent(QKeyEvent *event); - -private: - QString text; -}; diff --git a/examples/graphicsview/padnavigator/images/artsfftscope.png b/examples/graphicsview/padnavigator/images/artsfftscope.png index 4db003f..756a1cf 100644 Binary files a/examples/graphicsview/padnavigator/images/artsfftscope.png and b/examples/graphicsview/padnavigator/images/artsfftscope.png differ diff --git a/examples/graphicsview/padnavigator/main.cpp b/examples/graphicsview/padnavigator/main.cpp index dc5ff0c..f7d6f90 100644 --- a/examples/graphicsview/padnavigator/main.cpp +++ b/examples/graphicsview/padnavigator/main.cpp @@ -40,10 +40,6 @@ ****************************************************************************/ #include -#ifndef QT_NO_OPENGL -# include -#endif - #include "panel.h" int main(int argc, char *argv[]) diff --git a/examples/graphicsview/padnavigator/panel.cpp b/examples/graphicsview/padnavigator/panel.cpp index 28a3cb4..c088fbc 100644 --- a/examples/graphicsview/padnavigator/panel.cpp +++ b/examples/graphicsview/padnavigator/panel.cpp @@ -50,15 +50,15 @@ #endif #include -#include - Panel::Panel(int width, int height) - : selectedX(0), - selectedY(0), + : selectedIndex(0), + grid(width*height), width(width), height(height), flipped(false), - flipLeft(true) + flippingGroup(0), + rotationXanim(0), + rotationYanim(0) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -72,12 +72,9 @@ Panel::Panel(int width, int height) #endif setMinimumSize(50, 50); - selectionTimeLine = new QTimeLine(150, this); - flipTimeLine = new QTimeLine(500, this); - QRectF bounds((-width / 2.0) * 150, (-height / 2.0) * 150, width * 150, height * 150); - scene = new QGraphicsScene(bounds, this); + QGraphicsScene *scene = new QGraphicsScene(bounds, this); scene->setItemIndexMethod(QGraphicsScene::NoIndex); setScene(scene); @@ -90,28 +87,24 @@ Panel::Panel(int width, int height) ui->hostName->setFocus(); backItem = new RoundRectItem(bounds, embed->palette().window(), embed); - backItem->setTransform(QTransform().rotate(180, Qt::YAxis)); + backItem->setYRotation(180); backItem->setParentItem(baseItem); selectionItem = new RoundRectItem(QRectF(-60, -60, 120, 120), Qt::gray); selectionItem->setParentItem(baseItem); selectionItem->setZValue(-1); - selectionItem->setPos(posForLocation(0, 0)); - startPos = selectionItem->pos(); + selectionItem->setPos(posForLocation(0)); - grid = new QGraphicsItem **[height]; - + int currentIndex = 0; for (int y = 0; y < height; ++y) { - grid[y] = new QGraphicsItem *[width]; - for (int x = 0; x < width; ++x) { RoundRectItem *item = new RoundRectItem(QRectF(-54, -54, 108, 108), QColor(214, 240, 110, 128)); - item->setPos(posForLocation(x, y)); + item->setPos(posForLocation(currentIndex)); item->setParentItem(baseItem); item->setFlag(QGraphicsItem::ItemIsFocusable); - grid[y][x] = item; + grid[currentIndex++] = item; switch (qrand() % 9) { case 0: item->setPixmap(QPixmap(":/images/kontact_contacts.png")); break; @@ -131,14 +124,10 @@ Panel::Panel(int width, int height) } } - grid[0][0]->setFocus(); + grid.first()->setFocus(); connect(backItem, SIGNAL(activated()), this, SLOT(flip())); - connect(selectionTimeLine, SIGNAL(valueChanged(qreal)), - this, SLOT(updateSelectionStep(qreal))); - connect(flipTimeLine, SIGNAL(valueChanged(qreal)), - this, SLOT(updateFlipStep(qreal))); splash = new SplashItem; splash->setZValue(5); @@ -147,16 +136,15 @@ Panel::Panel(int width, int height) splash->grabKeyboard(); - updateSelectionStep(0); + //initialize the position + baseItem->setYRotation(selectionItem->x()/6.); + baseItem->setXRotation(selectionItem->y()/6.); setWindowTitle(tr("Pad Navigator Example")); } Panel::~Panel() { - for (int y = 0; y < height; ++y) - delete [] grid[y]; - delete [] grid; } void Panel::keyPressEvent(QKeyEvent *event) @@ -166,73 +154,93 @@ void Panel::keyPressEvent(QKeyEvent *event) return; } - selectedX = (selectedX + width + (event->key() == Qt::Key_Right) - (event->key() == Qt::Key_Left)) % width; - selectedY = (selectedY + height + (event->key() == Qt::Key_Down) - (event->key() == Qt::Key_Up)) % height; - grid[selectedY][selectedX]->setFocus(); - - selectionTimeLine->stop(); - startPos = selectionItem->pos(); - endPos = posForLocation(selectedX, selectedY); - selectionTimeLine->start(); + selectedIndex = (selectedIndex + grid.count() + (event->key() == Qt::Key_Right) - (event->key() == Qt::Key_Left) + + width * ((event->key() == Qt::Key_Down) - (event->key() == Qt::Key_Up))) % grid.count(); + grid[selectedIndex]->setFocus(); + + const QPointF pos = posForLocation(selectedIndex); + + const double angleY = pos.x() / 6., + angleX = pos.y() / 6.; + + QAnimationGroup *group = new QParallelAnimationGroup(); + + QVariantAnimation *anim = new QPropertyAnimation(baseItem, "xRotation"); + anim->setEndValue(angleX); + anim->setDuration(150); + anim->setEasingCurve(QEasingCurve::OutInSine); + group->addAnimation(anim); + + anim = new QPropertyAnimation(baseItem, "yRotation"); + anim->setEndValue(angleY); + anim->setDuration(150); + anim->setEasingCurve(QEasingCurve::OutInSine); + group->addAnimation(anim); + + anim = new QPropertyAnimation(selectionItem, "pos"); + anim->setEndValue(pos); + anim->setDuration(150); + anim->setEasingCurve(QEasingCurve::Linear); + group->addAnimation(anim); + + group->start(QAbstractAnimation::DeleteWhenStopped); } void Panel::resizeEvent(QResizeEvent *event) { QGraphicsView::resizeEvent(event); - fitInView(scene->sceneRect(), Qt::KeepAspectRatio); + fitInView(scene()->sceneRect(), Qt::KeepAspectRatio); } -void Panel::updateSelectionStep(qreal val) +void Panel::flip() { - QPointF newPos(startPos.x() + (endPos - startPos).x() * val, - startPos.y() + (endPos - startPos).y() * val); - selectionItem->setPos(newPos); - - QTransform transform; - yrot = newPos.x() / 6.0; - xrot = newPos.y() / 6.0; - transform.rotate(newPos.x() / 6.0, Qt::YAxis); - transform.rotate(newPos.y() / 6.0, Qt::XAxis); - baseItem->setTransform(transform); -} + grid[selectedIndex]->setFocus(); + + if (flippingGroup == 0) { + flippingGroup = new QParallelAnimationGroup(this); + + const qreal zoomOut = qreal(.75); + + //slight scaling down while flipping + QVariantAnimation *anim = new QPropertyAnimation(baseItem, "yScale"); + anim->setKeyValueAt(qreal(.5), zoomOut); + anim->setEndValue(1); + anim->setEasingCurve(QEasingCurve::OutInSine); + anim->setDuration(500); + flippingGroup->addAnimation(anim); + + anim = new QPropertyAnimation(baseItem, "xScale"); + anim->setKeyValueAt(qreal(.5), zoomOut); + anim->setEndValue(1); + anim->setEasingCurve(QEasingCurve::OutInSine); + anim->setDuration(500); + flippingGroup->addAnimation(anim); + + rotationXanim = new QPropertyAnimation(baseItem, "xRotation"); + rotationXanim->setEndValue(0); + rotationXanim->setDuration(500); + flippingGroup->addAnimation(rotationXanim); + + rotationYanim = new QPropertyAnimation(baseItem, "yRotation"); + rotationYanim->setStartValue(0); + rotationYanim->setEndValue(180); + rotationYanim->setDuration(500); + flippingGroup->addAnimation(rotationYanim); + } -void Panel::updateFlipStep(qreal val) -{ - qreal finalxrot = xrot - xrot * val; - qreal finalyrot; - if (flipLeft) - finalyrot = yrot - yrot * val - 180 * val; + if (flippingGroup->currentTime() != 0 && flippingGroup->direction() == QAbstractAnimation::Forward) + flippingGroup->setDirection(QAbstractAnimation::Backward); else - finalyrot = yrot - yrot * val + 180 * val; - QTransform transform; - transform.rotate(finalyrot, Qt::YAxis); - transform.rotate(finalxrot, Qt::XAxis); - qreal scale = 1 - sin(3.14 * val) * 0.3; - transform.scale(scale, scale); - baseItem->setTransform(transform); - if (val == 0) - grid[selectedY][selectedX]->setFocus(); -} + flippingGroup->setDirection(QAbstractAnimation::Forward); -void Panel::flip() -{ - if (flipTimeLine->state() == QTimeLine::Running) - return; - - if (flipTimeLine->currentValue() == 0) { - flipTimeLine->setDirection(QTimeLine::Forward); - flipTimeLine->start(); - flipped = true; - flipLeft = selectionItem->pos().x() < 0; - } else { - flipTimeLine->setDirection(QTimeLine::Backward); - flipTimeLine->start(); - flipped = false; - } + flippingGroup->start(); + flipped = !flipped; } -QPointF Panel::posForLocation(int x, int y) const +QPointF Panel::posForLocation(int index) const { + const int x = index % width, + y = index / width; return QPointF(x * 150, y * 150) - QPointF((width - 1) * 75, (height - 1) * 75); } diff --git a/examples/graphicsview/padnavigator/panel.h b/examples/graphicsview/padnavigator/panel.h index 03876b7..cc03530 100644 --- a/examples/graphicsview/padnavigator/panel.h +++ b/examples/graphicsview/padnavigator/panel.h @@ -40,10 +40,12 @@ ****************************************************************************/ #include +#include QT_BEGIN_NAMESPACE -class QTimeLine; class Ui_BackSide; +class QAnimationGroup; +class QPropertyAnimation; QT_END_NAMESPACE; class RoundRectItem; @@ -60,33 +62,24 @@ protected: void resizeEvent(QResizeEvent *event); private Q_SLOTS: - void updateSelectionStep(qreal val); - void updateFlipStep(qreal val); void flip(); private: - QPointF posForLocation(int x, int y) const; + QPointF posForLocation(int index) const; - QGraphicsScene *scene; - RoundRectItem *selectionItem; - RoundRectItem *baseItem; + QGraphicsWidget *selectionItem; + QGraphicsWidget *baseItem; RoundRectItem *backItem; QGraphicsWidget *splash; - QTimeLine *selectionTimeLine; - QTimeLine *flipTimeLine; - int selectedX, selectedY; + int selectedIndex; - QGraphicsItem ***grid; + QVector grid; - QPointF startPos; - QPointF endPos; - qreal xrot, yrot; - qreal xrot2, yrot2; - int width; int height; bool flipped; - bool flipLeft; - Ui_BackSide *ui; + + QAnimationGroup *flippingGroup; + QPropertyAnimation *rotationXanim, *rotationYanim; }; diff --git a/examples/graphicsview/padnavigator/roundrectitem.cpp b/examples/graphicsview/padnavigator/roundrectitem.cpp index c5dc35d..ec91966 100644 --- a/examples/graphicsview/padnavigator/roundrectitem.cpp +++ b/examples/graphicsview/padnavigator/roundrectitem.cpp @@ -44,72 +44,61 @@ #include RoundRectItem::RoundRectItem(const QRectF &rect, const QBrush &brush, QWidget *embeddedWidget) - : QGraphicsRectItem(rect), + : QGraphicsWidget(), + m_rect(rect), brush(brush), - timeLine(75), - lastVal(0), - opa(1), proxyWidget(0) { - connect(&timeLine, SIGNAL(valueChanged(qreal)), - this, SLOT(updateValue(qreal))); - if (embeddedWidget) { proxyWidget = new QGraphicsProxyWidget(this); proxyWidget->setFocusPolicy(Qt::StrongFocus); proxyWidget->setWidget(embeddedWidget); - proxyWidget->setGeometry(boundingRect().adjusted(25, 25, -25, -25)); } } void RoundRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { - QTransform x = painter->worldTransform(); - - QLineF unit = x.map(QLineF(0, 0, 1, 1)); - if (unit.p1().x() > unit.p2().x() || unit.p1().y() > unit.p2().y()) { - if (proxyWidget && proxyWidget->isVisible()) { + const bool widgetHidden = parentItem() == 0 || qAbs(static_cast(parentItem())->yRotation()) < 90; + + if (proxyWidget) { + if (widgetHidden) { proxyWidget->hide(); - proxyWidget->setGeometry(rect()); + } else { + if (!proxyWidget->isVisible()) { + proxyWidget->setGeometry(boundingRect().adjusted(25, 25, -25, -25)); + proxyWidget->show(); + proxyWidget->setFocus(); + } + painter->setBrush(brush); + painter->setPen(QPen(Qt::black, 1)); + painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + painter->drawRoundRect(m_rect); } - return; - } - - if (proxyWidget && !proxyWidget->isVisible()) { - proxyWidget->show(); - proxyWidget->setFocus(); - } - if (proxyWidget && proxyWidget->pos() != QPoint()) - proxyWidget->setGeometry(boundingRect().adjusted(25, 25, -25, -25)); - - painter->setOpacity(opacity()); - painter->setPen(Qt::NoPen); - painter->setBrush(QColor(0, 0, 0, 64)); - painter->drawRoundRect(rect().translated(2, 2)); + } else if (widgetHidden) { + painter->setPen(Qt::NoPen); + painter->setBrush(QColor(0, 0, 0, 64)); + painter->drawRoundRect(m_rect.translated(2, 2)); - if (!proxyWidget) { - QLinearGradient gradient(rect().topLeft(), rect().bottomRight()); + QLinearGradient gradient(m_rect.topLeft(), m_rect.bottomRight()); const QColor col = brush.color(); gradient.setColorAt(0, col); - gradient.setColorAt(1, col.dark(int(200 + lastVal * 50))); + gradient.setColorAt(1, col.dark(200)); painter->setBrush(gradient); - } else { - painter->setBrush(brush); + painter->setPen(QPen(Qt::black, 1)); + painter->drawRoundRect(m_rect); + if (!pix.isNull()) { + painter->scale(qreal(1.95), qreal(1.95)); + painter->drawPixmap(-pix.width() / 2, -pix.height() / 2, pix); + } } - painter->setPen(QPen(Qt::black, 1)); - painter->drawRoundRect(rect()); - if (!pix.isNull()) { - painter->scale(1.95, 1.95); - painter->drawPixmap(-pix.width() / 2, -pix.height() / 2, pix);; - } } QRectF RoundRectItem::boundingRect() const { - qreal penW = 0.5; - qreal shadowW = 2.0; - return rect().adjusted(-penW, -penW, penW + shadowW, penW + shadowW); + qreal penW = qreal(.5); + qreal shadowW = 2; + return m_rect.adjusted(-penW, -penW, penW + shadowW, penW + shadowW); } void RoundRectItem::setPixmap(const QPixmap &pixmap) @@ -119,46 +108,29 @@ void RoundRectItem::setPixmap(const QPixmap &pixmap) update(); } -qreal RoundRectItem::opacity() const -{ - RoundRectItem *parent = parentItem() ? (RoundRectItem *)parentItem() : 0; - return opa + (parent ? parent->opacity() : 0); -} - -void RoundRectItem::setOpacity(qreal opacity) -{ - opa = opacity; - update(); -} - void RoundRectItem::keyPressEvent(QKeyEvent *event) { - if (event->isAutoRepeat() || event->key() != Qt::Key_Return - || (timeLine.state() == QTimeLine::Running && timeLine.direction() == QTimeLine::Forward)) { - QGraphicsRectItem::keyPressEvent(event); + if (event->isAutoRepeat() || event->key() != Qt::Key_Return) { + QGraphicsWidget::keyPressEvent(event); return; } - timeLine.stop(); - timeLine.setDirection(QTimeLine::Forward); - timeLine.start(); + if (!proxyWidget) { + setXScale(qreal(.9)); + setYScale(qreal(.9)); + } emit activated(); } void RoundRectItem::keyReleaseEvent(QKeyEvent *event) { - if (event->key() != Qt::Key_Return) { - QGraphicsRectItem::keyReleaseEvent(event); + if (event->isAutoRepeat() || event->key() != Qt::Key_Return) { + QGraphicsWidget::keyReleaseEvent(event); return; } - timeLine.stop(); - timeLine.setDirection(QTimeLine::Backward); - timeLine.start(); -} -void RoundRectItem::updateValue(qreal value) -{ - lastVal = value; - if (!proxyWidget) - setTransform(QTransform().scale(1 - value / 10.0, 1 - value / 10.0)); + if (!proxyWidget) { + setXScale(1); + setYScale(1); + } } diff --git a/examples/graphicsview/padnavigator/roundrectitem.h b/examples/graphicsview/padnavigator/roundrectitem.h index 33e33d7..b0d44dd 100644 --- a/examples/graphicsview/padnavigator/roundrectitem.h +++ b/examples/graphicsview/padnavigator/roundrectitem.h @@ -40,15 +40,14 @@ ****************************************************************************/ #include -#include -#include #include +#include QT_BEGIN_NAMESPACE class QGraphicsProxyWidget; QT_END_NAMESPACE; -class RoundRectItem : public QObject, public QGraphicsRectItem +class RoundRectItem : public QGraphicsWidget { Q_OBJECT public: @@ -59,9 +58,6 @@ public: void setPixmap(const QPixmap &pixmap); - qreal opacity() const; - void setOpacity(qreal opacity); - Q_SIGNALS: void activated(); @@ -69,15 +65,9 @@ protected: void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); -private slots: - void updateValue(qreal value); - private: + QRectF m_rect; QBrush brush; QPixmap pix; - QTimeLine timeLine; - qreal lastVal; - qreal opa; - QGraphicsProxyWidget *proxyWidget; }; diff --git a/examples/graphicsview/padnavigator/splashitem.cpp b/examples/graphicsview/padnavigator/splashitem.cpp index 2a374bf..a83d4d5 100644 --- a/examples/graphicsview/padnavigator/splashitem.cpp +++ b/examples/graphicsview/padnavigator/splashitem.cpp @@ -46,12 +46,6 @@ SplashItem::SplashItem(QGraphicsItem *parent) : QGraphicsWidget(parent) { - opacity = 1.0; - - - timeLine = new QTimeLine(350); - timeLine->setCurveShape(QTimeLine::EaseInCurve); - connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(setValue(qreal))); text = tr("Welcome to the Pad Navigator Example. You can use the" " keyboard arrows to navigate the icons, and press enter" @@ -61,7 +55,6 @@ SplashItem::SplashItem(QGraphicsItem *parent) void SplashItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { - painter->setOpacity(opacity); painter->setPen(QPen(Qt::black, 2)); painter->setBrush(QColor(245, 245, 255, 220)); painter->setClipRect(rect()); @@ -79,14 +72,14 @@ void SplashItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWid void SplashItem::keyPressEvent(QKeyEvent * /* event */) { - if (timeLine->state() == QTimeLine::NotRunning) - timeLine->start(); -} + QVariantAnimation *anim = new QPropertyAnimation(this, "pos"); + anim->setEndValue(QPointF(x(), scene()->sceneRect().top() - rect().height())); + anim->setDuration(350); + anim->start(QAbstractAnimation::DeleteWhenStopped); -void SplashItem::setValue(qreal value) -{ - opacity = 1 - value; - setPos(x(), scene()->sceneRect().top() - rect().height() * value); - if (value == 1) - hide(); + anim = new QPropertyAnimation(this, "opacity"); + anim->setEndValue(0); + anim->start(QAbstractAnimation::DeleteWhenStopped); + + connect(anim, SIGNAL(finished()), SLOT(close())); } diff --git a/examples/graphicsview/padnavigator/splashitem.h b/examples/graphicsview/padnavigator/splashitem.h index 982bbe2..e2655ec 100644 --- a/examples/graphicsview/padnavigator/splashitem.h +++ b/examples/graphicsview/padnavigator/splashitem.h @@ -40,7 +40,6 @@ ****************************************************************************/ #include -#include #include class SplashItem : public QGraphicsWidget @@ -53,11 +52,6 @@ public: protected: void keyPressEvent(QKeyEvent *event); -private Q_SLOTS: - void setValue(qreal value); - private: - QTimeLine *timeLine; QString text; - qreal opacity; }; -- cgit v0.12 From bdbe84f8a8dbb50873e26829ee8a5127e21a0161 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 20 May 2009 17:18:32 +0200 Subject: Revert "QVariant has changed to use some QAtomic API which was missing" This reverts commit 9afa9ce3c0423e773e88d5c586595353815ac341. --- src/corelib/arch/qatomic_bootstrap.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/arch/qatomic_bootstrap.h index af76903..7584b84 100644 --- a/src/corelib/arch/qatomic_bootstrap.h +++ b/src/corelib/arch/qatomic_bootstrap.h @@ -92,20 +92,6 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValu return false; } -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) -{ - T *currentValue = _q_value; - _q_value = newValue; - return currentValue; -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - QT_END_NAMESPACE QT_END_HEADER -- cgit v0.12 From bbd7c13d0cf9d99413f2bea9a3acfba848e3520e Mon Sep 17 00:00:00 2001 From: David Boddie Date: Wed, 20 May 2009 18:22:17 +0200 Subject: Doc: Added a small example/test case for sequential animations. Reviewed-by: Trust Me --- doc/src/snippets/animation/sequential/icons.qrc | 6 +++ .../snippets/animation/sequential/icons/left.png | Bin 0 -> 413 bytes .../snippets/animation/sequential/icons/right.png | Bin 0 -> 414 bytes doc/src/snippets/animation/sequential/main.cpp | 50 +++++++++++++++++++++ .../snippets/animation/sequential/sequential.pro | 4 ++ doc/src/snippets/animation/sequential/tracer.cpp | 25 +++++++++++ doc/src/snippets/animation/sequential/tracer.h | 23 ++++++++++ 7 files changed, 108 insertions(+) create mode 100644 doc/src/snippets/animation/sequential/icons.qrc create mode 100644 doc/src/snippets/animation/sequential/icons/left.png create mode 100644 doc/src/snippets/animation/sequential/icons/right.png create mode 100644 doc/src/snippets/animation/sequential/main.cpp create mode 100644 doc/src/snippets/animation/sequential/sequential.pro create mode 100644 doc/src/snippets/animation/sequential/tracer.cpp create mode 100644 doc/src/snippets/animation/sequential/tracer.h diff --git a/doc/src/snippets/animation/sequential/icons.qrc b/doc/src/snippets/animation/sequential/icons.qrc new file mode 100644 index 0000000..d55f797 --- /dev/null +++ b/doc/src/snippets/animation/sequential/icons.qrc @@ -0,0 +1,6 @@ + + + icons/left.png + icons/right.png + + diff --git a/doc/src/snippets/animation/sequential/icons/left.png b/doc/src/snippets/animation/sequential/icons/left.png new file mode 100644 index 0000000..5dd8da0 Binary files /dev/null and b/doc/src/snippets/animation/sequential/icons/left.png differ diff --git a/doc/src/snippets/animation/sequential/icons/right.png b/doc/src/snippets/animation/sequential/icons/right.png new file mode 100644 index 0000000..ac61326 Binary files /dev/null and b/doc/src/snippets/animation/sequential/icons/right.png differ diff --git a/doc/src/snippets/animation/sequential/main.cpp b/doc/src/snippets/animation/sequential/main.cpp new file mode 100644 index 0000000..aff8f29 --- /dev/null +++ b/doc/src/snippets/animation/sequential/main.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include "tracer.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QWidget window; + window.resize(720, 96); + window.show(); + + QLabel *label1 = new QLabel(&window); + label1->setPixmap(QPixmap(":/icons/left.png")); + label1->move(16, 16); + label1->show(); + + QLabel *label2 = new QLabel(&window); + label2->setPixmap(QPixmap(":/icons/right.png")); + label2->move(320, 16); + label2->show(); + + QPropertyAnimation *anim1 = new QPropertyAnimation(label1, "pos"); + anim1->setDuration(2500); + anim1->setStartValue(QPoint(16, 16)); + anim1->setEndValue(QPoint(320, 16)); + + QPropertyAnimation *anim2 = new QPropertyAnimation(label2, "pos"); + anim2->setDuration(2500); + anim2->setStartValue(QPoint(320, 16)); + anim2->setEndValue(QPoint(640, 16)); + + QSequentialAnimationGroup group; + group.addAnimation(anim1); + group.addAnimation(anim2); + + Tracer tracer(&window); + + QObject::connect(anim1, SIGNAL(valueChanged(QVariant)), + &tracer, SLOT(recordValue(QVariant))); + QObject::connect(anim2, SIGNAL(valueChanged(QVariant)), + &tracer, SLOT(recordValue(QVariant))); + QObject::connect(anim1, SIGNAL(finished()), &tracer, SLOT(checkValue())); + QObject::connect(anim2, SIGNAL(finished()), &tracer, SLOT(checkValue())); + + group.start(); + return app.exec(); +} diff --git a/doc/src/snippets/animation/sequential/sequential.pro b/doc/src/snippets/animation/sequential/sequential.pro new file mode 100644 index 0000000..fcf017f --- /dev/null +++ b/doc/src/snippets/animation/sequential/sequential.pro @@ -0,0 +1,4 @@ +HEADERS = tracer.h +RESOURCES = icons.qrc +SOURCES = main.cpp \ + tracer.cpp diff --git a/doc/src/snippets/animation/sequential/tracer.cpp b/doc/src/snippets/animation/sequential/tracer.cpp new file mode 100644 index 0000000..49bd51e --- /dev/null +++ b/doc/src/snippets/animation/sequential/tracer.cpp @@ -0,0 +1,25 @@ +#include +#include +#include +#include "tracer.h" + +Tracer::Tracer(QObject *parent) + : QObject(parent) +{ +} + +void Tracer::checkValue() +{ + QAbstractAnimation *animation = static_cast(sender()); + if (time != animation->duration()) { + qDebug() << "Animation's last recorded time" << time; + qDebug() << "Expected" << animation->duration(); + } +} + +void Tracer::recordValue(const QVariant &value) +{ + QAbstractAnimation *animation = static_cast(sender()); + this->value = value; + time = animation->currentTime(); +} diff --git a/doc/src/snippets/animation/sequential/tracer.h b/doc/src/snippets/animation/sequential/tracer.h new file mode 100644 index 0000000..1adb018 --- /dev/null +++ b/doc/src/snippets/animation/sequential/tracer.h @@ -0,0 +1,23 @@ +#ifndef TRACER_H +#define TRACER_H + +#include +#include + +class Tracer : public QObject +{ + Q_OBJECT + +public: + Tracer(QObject *parent = 0); + +public slots: + void checkValue(); + void recordValue(const QVariant &value); + +private: + QVariant value; + int time; +}; + +#endif -- cgit v0.12 From 9e5daecead75e1c7a77679a04a14cee9fd616215 Mon Sep 17 00:00:00 2001 From: Thomas Sondergaard Date: Wed, 20 May 2009 21:22:00 +0200 Subject: Danish translations --- translations/assistant_da.ts | 1134 ++++++++ translations/qt_da.ts | 6317 ++++++++++++++++++++++++++++++++++++++++++ translations/qt_help_da.ts | 354 +++ 3 files changed, 7805 insertions(+) create mode 100644 translations/assistant_da.ts create mode 100644 translations/qt_da.ts create mode 100644 translations/qt_help_da.ts diff --git a/translations/assistant_da.ts b/translations/assistant_da.ts new file mode 100644 index 0000000..d039248 --- /dev/null +++ b/translations/assistant_da.ts @@ -0,0 +1,1134 @@ + + + + + + AboutDialog + + + &Close + &Luk + + + + BookmarkDialog + + + + + + + Bookmarks + Favoritter + + + + Add Bookmark + Føj til Favoritter + + + + Bookmark: + Favorit: + + + + Add in Folder: + Føj til mappen: + + + + + + + + + + New Folder + Ny mappe + + + + Delete Folder + Slet mappe + + + + Rename Folder + Omdøb mappe + + + + BookmarkManager + + + Bookmarks + Favoritter + + + + Remove + Fjern + + + You are going to delete a Folder, this will also<br>remove it's content. Are you sure to continue? + Ved at slette denne mappe fjernes hele mappens<br>indhold. Ă˜nsker du alligevel at slette? + + + + + New Folder + Ny mappe + + + + You are about to delete a folder which means that its content<br>will also be removed. Do you want to continue? + Ved at slette denne mappe fjernes hele mappens indhold.<br>Ă˜nsker du alligevel at slette? + + + + BookmarkWidget + + + Remove + Fjern + + + + Delete Folder + Slet mappe + + + + Rename Folder + Omdøb mappe + + + + Show Bookmark + Vis favorit + + + + Show Bookmark in New Tab + Vis favorit pĂ¥ ny fane + + + + Delete Bookmark + Slet favorit + + + + Rename Bookmark + Omdøb favorit + + + + Search for: + Søg efter: + + + + Add + Tilføj + + + + CentralWidget + + + Add new page + Tilføj ny side + + + + Close current page + Luk nuværende side + + + + Print Document + Udskriv dokument + + + + + unknown + ukendt + + + + Add New Page + Tilføj ny side + + + + Close This Page + Luk denne side + + + + Close Other Pages + Luk de andre sider + + + + Add Bookmark for this Page... + Føj denne side til Favoritter... + + + + Search + Søg + + + + ContentWindow + + + Open Link + Ă…bn link + + + + Open Link in New Tab + Ă…bn link pĂ¥ ny fane + + + + FilterNameDialogClass + + + FilterNameDialog + FilterNavnDialog + + + + Filter Name: + Filternavn: + + + + FindWidget + + + Previous + Forrige + + + + Next + Næste + + + + Case Sensitive + Der skelnes mellem store og smĂ¥ bogstaver + + + + Whole words + Hele ord + + + + <img src="%1">&nbsp;Search wrapped + <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped + <img src="%1">&nbsp;Søgning startet forfra + + + + FontPanel + + + Font + Skrifttype + + + + &Writing system + &Skrivesystem + + + + &Family + &Familie + + + + &Style + &Stil + + + + &Point size + &Punktstørrelse + + + + HelpViewer + + + Help + Hjælp + + + + OK + + + + + <title>Error 404...</title><div align="center"><br><br><h1>The page could not be found</h1><br><h3>'%1'</h3></div> + <title>Fejl 404...</title><div align="center"><br><br><h1>Siden blev ikke fundet</h1><br><h3>'%1'</h3></div> + + + + Copy &Link Location + KopiĂ©r &linkets placering + + + + Open Link in New Tab Ctrl+LMB + Ă…bn link pĂ¥ ny fane Ctrl+LMB + + + + Open Link in New Tab + Ă…bn link pĂ¥ ny fane + + + + <b>Page not found:<p>%1.</p></b> + <b>Kunne ikke finde siden:<p>%1.</p></b> + + + + Unable to launch external application. + + Kunne ikke starte ekstern applikation. + + + + + IndexWindow + + + &Look for: + &Søg efter: + + + + Open Link + Ă…bn link + + + + Open Link in New Tab + Ă…bn link pĂ¥ ny fane + + + + InstallDialog + + + + Install Documentation + InstallĂ©r dokumentation + + + + Downloading documentation info... + Downloader dokumentationsinformation... + + + + Download canceled. + Download blev annulleret. + + + + + + Done. + Færdig. + + + + The file %1 already exists. Do you want to overwrite it? + Filen %1 findes allerede. Ă˜nsker du at overskrive? + + + + Unable to save the file %1: %2. + Kunne ikke gemme filen %1: %2. + + + + Downloading %1... + Downloader %1... + + + + + + Download failed: %1. + Download mislykkedes: %1. + + + + Documentation info file is corrupt! + Dokumentationsinformationsfilen er ødelagt! + + + + Download failed: Downloaded file is corrupted. + Download mislykkedes: Den downloadede fil er ødelagt. + + + + Installing documentation %1... + Installerer dokumentation %1... + + + + Error while installing documentation: +%1 + Der opstod fejl under installation af dokumentation: +%1 + + + + Available Documentation: + Tilgængeligt dokumentation: + + + + Install + InstallĂ©r + + + + Cancel + Annuller + + + + Close + Luk + + + + Installation Path: + Installationssti: + + + + ... + + + + + MainWindow + + + + Index + Indeks + + + + + Contents + Indhold + + + + + Bookmarks + Favoritter + + + + + Search + Søg + + + + + + Qt Assistant + + + + + + Unfiltered + Ufiltreret + + + Page Set&up... + Side&opsætning... + + + Print Preview... + Vis udskrift... + + + &Print... + &Udskriv... + + + CTRL+P + Ctrl+U + + + + New &Tab + &Ny Fane + + + CTRL+T + Ctrl+N + + + + &Close Tab + &Luk fane + + + CTRL+W + Ctrl+L + + + + &Quit + &Afslut + + + CTRL+Q + Ctrl+A + + + &Copy selected Text + &KopiĂ©r markeret tekst + + + Ctrl+C + Ctrl+K + + + + &Find in Text... + &Find i tekst... + + + + Ctrl+F + + + + + Find &Next + Find N&æste + + + + F3 + + + + + Find &Previous + Find fo&rrige + + + + Shift+F3 + + + + + Preferences... + Indstillinger... + + + + Zoom &in + Zoom &ind + + + + Ctrl++ + + + + + Zoom &out + Zoom u&d + + + + Ctrl+- + + + + + Normal &Size + Normal &størrelse + + + + Ctrl+0 + + + + + &Home + &Hjem + + + + Ctrl+Home + + + + + &Back + &Tilbage + + + + &Forward + Fr&em + + + Sync with Table of Contents + SynkronisĂ©r med Indholdsfortegnelse + + + + Next Page + Næste side + + + + Ctrl+Alt+Right + Ctrl+Alt+Højre + + + + Previous Page + Forrige side + + + + Ctrl+Alt+Left + Ctrl+Alt+Venstre + + + + Add Bookmark... + Føj til Favoritter... + + + + About... + Om... + + + + Navigation Toolbar + Navigationsværktøjslinie + + + + Toolbars + Værktøjslinier + + + + Filter Toolbar + Filtrer værktøjslinie + + + + Filtered by: + Filtreret efter: + + + + Address Toolbar + Adresseværktøjslinie + + + + Address: + Adresse: + + + + Could not find the associated content item. + Det tilhørende indholdselement kunne ikke findes. + + + + Open Source Edition + + + + + This version of Qt Assistant is part of the Qt Open Source Edition, for use in the development of Open Source applications. Qt is a comprehensive C++ framework for cross-platform application development. + Denne version af Qt Assistant er en del af Qt Open Source Edition til brug med henblik pĂ¥ udvikling af Open Source-applikationer. Qt er et omfattende C++ framework for cross-platform applikationsudvikling. + + + + This program is licensed to you under the terms of the Qt Commercial License Agreement. For details, see the file LICENSE that came with this software distribution. + Dette program er omfattet af Qt Commercial License Agreement. Se filen LICENCE, der var vedlagt denne software-distribution, for yderligere detaljer. + + + + About %1 + Om %1 + + + + Updating search index + Opdaterer søgeindeks + + + + Looking for Qt Documentation... + Søger efter Qt-dokumentation... + + + + &Window + &Vindue + + + + Minimize + MinimĂ©r + + + + Ctrl+M + Ctrl+M + + + + Zoom + + + + + &File + &Filer + + + + &Edit + &RedigĂ©r + + + + &View + &Vis + + + + &Go + &GĂ¥ til + + + + &Bookmarks + F&avoritter + + + + &Help + &Hjælp + + + + You need a commercial Qt license for development of proprietary (closed source) applications. Please see <a href="http://trolltech.com/company/about/businessmodel">http://trolltech.com/company/about/businessmodel</a> for an overview of Qt licensing. + + + + ALT+O + Alt+F + + + CTRL+D + Ctrl+Ă˜ + + + Ctrl+P + Ctrl+U + + + + Ctrl+T + Ctrl+N + + + + Ctrl+W + Ctrl+L + + + + Ctrl+Q + Ctrl+A + + + + Alt+C + Alt+L + + + + Alt+I + + + + + Alt+O + Alt+F + + + + Alt+S + + + + + Ctrl+D + Ctrl+Ă˜ + + + + PreferencesDialog + + + + + Add Documentation + Tilføj dokumentation + + + + Qt Compressed Help Files (*.qch) + Qt komprimeret hjælpefil (*.qch) + + + + The specified file is not a valid Qt Help File! + Den anførte fil er ikke en gyldig Qt hjælpefil! + + + + The namespace %1 is already registered! + Navnerummet %1 er allerede registreret! + + + + Use custom settings + Benyt brugerdefineret opsætning + + + + PreferencesDialogClass + + + Preferences + Indstillinger + + + + Fonts + Skrifttyper + + + + Font settings: + Indstillinger for skrifttype: + + + + Browser + + + + + Application + Applikation + + + + Filters + Filtre + + + + Filter: + Filter: + + + + Attributes: + Attributter: + + + + 1 + + + + + Add + Tilføj + + + + + Remove + Fjern + + + + Documentation + Dokumentation + + + + Registered Documentation: + Registreret dokumentation: + + + + Add... + Tilføj... + + + + Network + Netværk + + + + Use Http Proxy + Benyt Http Proxy + + + + Http Proxy: + + + + + Port: + + + + + QObject + + + The specified collection file does not exist! + Den angivne hjælpesamling findes ikke! + + + + Missing collection file! + Hjælpesamling mangler! + + + + Invalid URL! + Ugyldig URL! + + + + Missing URL! + URL mangler! + + + + + + Unknown widget: %1 + Ukendt widget: %1 + + + + + + Missing widget! + Widget mangler! + + + + + The specified Qt help file does not exist! + Den angivne Qt-hjælpefil findes ikke! + + + + + Missing help file! + Hjælpefilen mangler! + + + + Unknown option: %1 + Ukendt parameter: %1 + + + + + Qt Assistant + + + + + Could not register documentation file +%1 + +Reason: +%2 + Kunne ikke registrere dokumentationsfil +%1 + +Ă…rsag: +%2 + + + + Documentation successfully registered. + Dokumentationen blev registreret. + + + + Could not unregister documentation file +%1 + +Reason: +%2 + Kunne ikke afregistrere dokumentationsfil +%1 + +Ă…rsag: +%2 + + + + Documentation successfully unregistered. + Dokumentationen blev afregistreret. + + + + The specified collection file could not be read! + Den angivne hjælpesamling kunne ikke læses! + + + + + Bookmark + Favorit + + + + QtDocInstaller + + + The file %1 could not be registered successfully! + +Reason: %2 + Filen %1 kunne ikke registreres! + +Ă…rsag: %2 + + + + RemoteControl + + + Debugging Remote Control + + + + + Received Command: %1 %2 + Modtaget kommando: %1 %2 + + + + SearchWidget + + + &Copy + &KopiĂ©r + + + + Copy &Link Location + KopiĂ©r &linkets placering + + + + + Open Link in New Tab + Ă…bn link pĂ¥ ny fane + + + + Select All + MarkĂ©r alt + + + + Open Link + Ă…bn link + + + + TopicChooser + + + Choose a topic for <b>%1</b>: + Vælg et emne for <b>%1</b>: + + + + Choose Topic + Vælg emne + + + + &Topics + &Emner + + + + &Display + &Vis + + + + &Close + &Luk + + + TopicChooser + Emnevælger + + + unnamed + unavngivet + + + diff --git a/translations/qt_da.ts b/translations/qt_da.ts new file mode 100644 index 0000000..9350687 --- /dev/null +++ b/translations/qt_da.ts @@ -0,0 +1,6317 @@ + + + + + AudioOutput + + + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> + <html>Audio-playback-enheden<b>%1</b> virker ikke.<br/>Falder tilbage til <b>%2</b>.</html> + + + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> + <html>Skifter til audio-playback-enheden, <b>%1</b><br/>der lige er blevet tilgængeligt og har en højere præference.</html> + + + Revert back to device '%1' + GĂ¥ tilbage til enheden '%1' + + + + CloseButton + + + Close Tab + Luk fane + + + + Phonon:: + + + Notifications + Meddelelser + + + Music + Musik + + + Video + + + + Communication + Kommunikation + + + Games + Spil + + + Accessibility + Tilgængelighed + + + + Phonon::Gstreamer::Backend + + + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled. + Advarsel: Det ser ikke ud til, at gstreamer0.10-plugins-good pakken er installeret. + Nogle videofunktioner er deaktiveret. + + + Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled + Advarsel: Det ser ikke ud til, at base GStreamer plugins er installeret. + Al audio- og videosupport er deaktiveret + + + + Phonon::Gstreamer::MediaObject + + + Cannot start playback. + +Check your Gstreamer installation and make sure you +have libgstreamer-plugins-base installed. + Kan ikke starte playback. + +Tjek Gstreamer-installationen og kontrollĂ©r, at +libgstreamer-plugins-base er installeret. + + + A required codec is missing. You need to install the following codec(s) to play this content: %0 + Der mangler et codec. Følgende codecs skal installeres for at afspille dette indhold: %0 + + + Could not open media source. + Kunne ikke Ă¥bne mediekilden. + + + Invalid source type. + Ugyldig kilde. + + + Could not locate media source. + Kunne ikke lokalisere mediekilden. + + + Could not open audio device. The device is already in use. + Kunne ikke Ă¥bne lydenheden. Enheden er allerede i brug. + + + Could not decode media source. + Kunne ikke afkode mediekilden. + + + + Phonon::VolumeSlider + + Volume: %1% + + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% + Anvend denne skyder til at indstille lydstyrken. Længst til venstre er 0% og længst til højre er %1% + + + + Q3Accel + + + %1, %2 not defined + %1, %2 ikke definerede + + + Ambiguous %1 not handled + Tvetydig %1 ikke behandlet + + + + Q3DataTable + + + True + Sandt + + + False + Falsk + + + Insert + Indsæt + + + Update + Opdater + + + Delete + Slet + + + + Q3FileDialog + + + Copy or Move a File + KopiĂ©r eller flyt en fil + + + Read: %1 + Læs: %1 + + + Write: %1 + Skriv: %1 + + + Cancel + Annuller + + + + All Files (*) + Alle filer (*) + + + Name + Navn + + + Size + Størrelse + + + Type + + + + Date + Dato + + + Attributes + Attributter + + + &OK + &OK + + + Look &in: + Kig &i: + + + File &name: + Fil&navn: + + + File &type: + Fil&type: + + + Back + Tilbage + + + One directory up + En mappe op + + + Create New Folder + Opret ny folder + + + List View + Listevisning + + + Detail View + Detaljevisning + + + Preview File Info + Vis filinformation + + + Preview File Contents + Vis filindhold + + + Read-write + Læs-skriv + + + Read-only + Skrivebeskyttet + + + Write-only + Write-only + + + Inaccessible + Utilgængelig + + + Symlink to File + Symlink til Fil + + + Symlink to Directory + Symlink til katalog + + + Symlink to Special + Symlink til Speciel + + + File + Fil + + + Dir + Katalog + + + Special + Speciel + + + + Open + Ă…bn + + + + Save As + Gem som + + + &Open + &Ă…bn + + + &Save + &Gem + + + &Rename + &Omdøb + + + &Delete + &Slet + + + R&eload + Gen&indlæs + + + Sort by &Name + SortĂ©r efter n&avn + + + Sort by &Size + SortĂ©r efter s&tørrelse + + + Sort by &Date + SortĂ©r efter &dato + + + &Unsorted + &Usorteret + + + Sort + SortĂ©r + + + Show &hidden files + Vis s&kjulte filer + + + the file + filen + + + the directory + kataloget + + + the symlink + symlinket + + + Delete %1 + Slet %1 + + + <qt>Are you sure you wish to delete %1 "%2"?</qt> + <qt>Er du sikker pĂ¥, at du vil slette %1 "%2"?</qt> + + + &Yes + &Ja + + + &No + &Nej + + + New Folder 1 + Ny folder 1 + + + New Folder + Ny folder + + + New Folder %1 + Ny folder %1 + + + Find Directory + Find katalog + + + Directories + Kataloger + + + Directory: + Katalog: + + + Error + Fejl + + + %1 +File not found. +Check path and filename. + %1 +Filen blev ikke fundet. +KontrollĂ©r sti og filnavn. + + + All Files (*.*) + Alle filer (*.*) + + + Open + Ă…bn + + + Select a Directory + Vælg et katalog + + + + Q3LocalFs + + Could not read directory +%1 + Kunne ikke læse katalog +%1 + + + Could not create directory +%1 + Kunne ikke oprette katalog +%1 + + + Could not remove file or directory +%1 + Kunne ikke fjerne fil eller katalog +%1 + + + Could not rename +%1 +to +%2 + Kunne ikke omdøbe +%1 +to +%2 + + + Could not open +%1 + Kunne ikke Ă¥bne +%1 + + + Could not write +%1 + Kunne ikke skrive +%1 + + + + Q3MainWindow + + + Line up + Linie op + + + Customize... + Tilpas... + + + + Q3NetworkProtocol + + + Operation stopped by the user + Brugeren stoppede handlingen + + + + Q3ProgressDialog + + Cancel + Annuller + + + + Q3TabDialog + + OK + + + + Apply + Udfør + + + Help + Hjælp + + + Defaults + Standarder + + + Cancel + Annuller + + + + Q3TextEdit + + + &Undo + &Fortryd + + + &Redo + &Gendan + + + Cu&t + &Klip + + + &Copy + K&opiĂ©r + + + &Paste + &Sæt ind + + + Clear + Ryd + + + Select All + MarkĂ©r alt + + + + Q3TitleBar + + + System + + + + Restore up + Gendan op + + + Minimize + Minimer + + + Restore down + Gendan ned + + + Maximize + MaksimĂ©r + + + Close + Luk + + + Contains commands to manipulate the window + Indeholder kommandoer til indstilling af vinduet + + + Puts a minimized back to normal + Sætter et minimeret vindue til normal størrelse + + + Moves the window out of the way + Flytter vinduet væk + + + Puts a maximized window back to normal + Sætter et maksimeret vindue til normal størrelse + + + Makes the window full screen + Gør vinduet til fuld skærm + + + Closes the window + Lukker vinduet + + + Displays the name of the window and contains controls to manipulate it + Viser vinduets navn og indeholder kontroller til indstilling af vinduet + + + + Q3ToolBar + + + More... + Mere... + + + + Q3UrlOperator + + The protocol `%1' is not supported + Protokollen '%1' understøttes ikke + + + The protocol `%1' does not support listing directories + Protokollen '%1' understøtter ikke opremsning af kataloger + + + The protocol `%1' does not support creating new directories + Protokollen '%1' understøtter ikke oprettelse af nye kataloger + + + The protocol `%1' does not support removing files or directories + Protokollen '%1' understøtter ikke, at filer eller kataloger fjernes + + + The protocol `%1' does not support renaming files or directories + Protokollen '%1' understøtter ikke, at filer eller kataloger omdøbes + + + The protocol `%1' does not support getting files + Protokollen '%1' understøtter ikke hentning af filer + + + The protocol `%1' does not support putting files + Protokollen '%1' understøtter ikke upload af filer + + + The protocol `%1' does not support copying or moving files or directories + Protokollen '%1' understøtter ikke kopiering eller flytning af filer eller kataloger + + + (unknown) + (ukendt) + + + + Q3Wizard + + + &Cancel + &Annuller + + + < &Back + < &Tilbage + + + &Next > + &Næste > + + + &Finish + &Udfør + + + &Help + &Hjælp + + + + QAbstractSocket + + Host not found + Host blev ikke fundet + + + + Connection refused + Forbindelse afvist + + + Connection timed out + Forbindelsen timed out + + + Operation on socket is not supported + Socket-operation ikke understøttet + + + Socket operation timed out + Socket-operation timed out + + + Socket is not connected + Socket ikke forbundet + + + Network unreachable + Netværket er ikke tilgængeligt + + + + QAbstractSpinBox + + + &Step up + &Trin op + + + Step &down + Trin &ned + + + &Select All + &Vælg alle + + + + QApplication + + + Activate + AktivĂ©r + + + + Executable '%1' requires Qt %2, found Qt %3. + Eksekverbar '%1' kræver Qt %2, ikke fundet Qt %3. + + + Incompatible Qt Library Error + Inkompatibel Qt Library fejl + + + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + + + + + Activates the program's main window + Aktiverer programmets hovedvindue + + + + QAxSelect + + Select ActiveX Control + Vælg ActiveX-kontrol + + + OK + + + + &Cancel + &Annuller + + + COM &Object: + COM &Objekt: + + + + QCheckBox + + + Uncheck + Fjern markering + + + Check + Kryds af + + + Toggle + SlĂ¥ til/fra + + + + QColorDialog + + + Hu&e: + Ton&e: + + + &Sat: + &Mæt: + + + &Val: + &Vær: + + + &Red: + &Rød: + + + &Green: + &Grøn: + + + Bl&ue: + Bl&Ă¥: + + + A&lpha channel: + Al&fa-kanal: + + + Select Color + Vælg farve + + + &Basic colors + &Basisfarver + + + &Custom colors + &Egne farver + + + &Add to Custom Colors + &Føj til egne farver + + + + QComboBox + + Open + Ă…bn + + + + False + Falsk + + + True + Sandt + + + + Close + Luk + + + + QCoreApplication + + + %1: key is empty + QSystemSemaphore + %1: nøgle er tom + + + %1: unable to make key + QSystemSemaphore + %1: kunne ikke lave nøgle + + + %1: ftok failed + QSystemSemaphore + %1: ftok mislykkedes + + + + QDB2Driver + + + Unable to connect + Kunne ikke skabe forbindelse + + + Unable to commit transaction + Kunne ikke gennemføre transaktion + + + Unable to rollback transaction + Kunne ikke tilbagetrække transaktion + + + Unable to set autocommit + Kunne ikke aktivere autocommit + + + + QDB2Result + + Unable to execute statement + Kunne ikke udføre statement + + + Unable to prepare statement + Kunne ikke forberede udsagn + + + Unable to bind variable + Kunne ikke binde variabel + + + Unable to fetch record %1 + Kunne ikke hente post %1 + + + Unable to fetch next + Kunne ikke hente næste + + + Unable to fetch first + Kunne ikke hente første + + + + QDateTimeEdit + + + AM + + + + am + + + + PM + + + + pm + + + + + QDial + + + QDial + + + + SpeedoMeter + Speedometer + + + SliderHandle + + + + + QDialog + + + What's This? + Hvad er dette? + + + Done + Udført + + + + QDialogButtonBox + + + OK + + + + + &OK + + + + &Save + &Gem + + + Save + Gem + + + Open + Ă…bn + + + &Cancel + &Annuller + + + Cancel + Annuller + + + &Close + &Luk + + + Close + Luk + + + Apply + Udfør + + + Reset + Nulstil + + + Help + Hjælp + + + Don't Save + Gem ikke + + + Discard + KassĂ©r + + + &Yes + &Ja + + + Yes to &All + Ja til &alle + + + &No + &Nej + + + N&o to All + Ne&j til alle + + + Save All + Gem alle + + + Abort + Afbryd + + + Retry + Prøv igen + + + Ignore + Ignorer + + + Restore Defaults + Gendan standardværdier + + + Close without Saving + Luk uden at gemme + + + + QDirModel + + + Name + Navn + + + Size + Størrelse + + + Kind + Match OS X Finder + Type + + + Type + All other platforms + + + + Date Modified + Ændringsdato + + + + QDockWidget + + + Close + Luk + + + Dock + LĂ¥st + + + Float + Flydende + + + + QDoubleSpinBox + + More + Mere + + + Less + Mindre + + + + QErrorMessage + + + Debug Message: + Debug-besked: + + + Warning: + Advarsel: + + + Fatal Error: + Fatal fejl: + + + &Show this message again + &Vis denne besked igen + + + &OK + + + + + QFile + + Destination file exists + Destinationsfil findes + + + Cannot open %1 for input + Kan ikke Ă¥bne %1 til input + + + Cannot open for output + Kan ikke Ă¥bne til output + + + Failure to write block + Kunne ikke skrive blok + + + Cannot create %1 for output + Kunne ikke oprette %1 til output + + + + QFileDialog + + All Files (*) + Alle filer (*) + + + Directories + Kataloger + + + &Open + &Ă…bn + + + &Save + &Gem + + + Open + Ă…bn + + + %1 already exists. +Do you want to replace it? + %1 findes allerede. +Ă˜nsker du at erstatte den? + + + %1 +File not found. +Please verify the correct file name was given. + %1 +Filen kunne ikke findes. +KontrollĂ©r, at det rigtige filnavn er indtastet. + + + + My Computer + Min computer + + + &Rename + &Omdøb + + + &Delete + &Slet + + + Show &hidden files + Vis s&kjulte filer + + + Back + Tilbage + + + Parent Directory + Ovenliggende katalog + + + List View + Listevisning + + + Detail View + Detaljevisning + + + Files of type: + Filer af typen: + + + Directory: + Katalog: + + + %1 +Directory not found. +Please verify the correct directory name was given. + %1 +Katalog kunne ikke findes. +KontrollĂ©r, at det rigtige katalognavn er indtastet. + + + '%1' is write protected. +Do you want to delete it anyway? + '%1' er skrivebeskyttet. +Ă˜nsker du alligevel at slette? + + + Are sure you want to delete '%1'? + Er du sikker pĂ¥, at '%1' skal slettes? + + + Could not delete directory. + Kunne ikke slette kataloget. + + + Recent Places + Aktuelle steder + + + + All Files (*.*) + Alle filer (*.*) + + + Save As + Gem som + + + + Drive + Drev + + + File + Fil + + + Unknown + Ukendt + + + Find Directory + Find katalog + + + Show + Vis + + + Forward + Frem + + + + New Folder + Ny folder + + + &New Folder + &Ny folder + + + &Choose + &Vælg + + + + Remove + Fjern + + + File &name: + &Filnavn: + + + Look in: + Søg i: + + + Create New Folder + Opret ny folder + + + + QFileSystemModel + + + Invalid filename + Ugyldigt filnavn + + + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. + <b>Navnet, %1, kan ikke benyttes.</b><p>Brug et andet navn med færre tegn og ingen kommatering. + + + Name + Navn + + + Size + Størrelse + + + Kind + Match OS X Finder + Type + + + Type + All other platforms + + + + Date Modified + Ændringsdato + + + + My Computer + Min computer + + + Computer + + + + %1 TB + %1 TB + + + %1 GB + %1 GB + + + %1 MB + %1 MB + + + %1 KB + %1 KB' + + + %1 bytes + %1 bytes + + + + QFontDatabase + + Normal + + + + Bold + Fed + + + Demi Bold + + + + Black + Sort + + + Demi + + + + Light + Lys + + + Italic + Kursiv + + + Oblique + SkrĂ¥t + + + Any + Alle + + + Latin + + + + Greek + Græsk + + + Cyrillic + Kyrillisk + + + Armenian + Armensk + + + Hebrew + Hebræisk + + + Arabic + Arabisk + + + Syriac + Syrisk + + + Thaana + + + + Devanagari + + + + Bengali + Bengalsk + + + Gurmukhi + + + + Gujarati + + + + Oriya + + + + Tamil + + + + Telugu + + + + Kannada + + + + Malayalam + + + + Sinhala + + + + Thai + Thailandsk + + + Lao + + + + Tibetan + Tibetansk + + + Myanmar + + + + Georgian + georgisk + + + Khmer + + + + Simplified Chinese + Forenklet kinesisk + + + Traditional Chinese + Traditionelt kinesisk + + + Japanese + Japansk + + + Korean + Koreansk + + + Vietnamese + Vietnamesisk + + + Symbol + + + + Ogham + + + + Runic + + + + + QFontDialog + + + &Font + S&krifttype + + + Font st&yle + S&til + + + &Size + &Størrelse + + + Effects + Effekter + + + Stri&keout + &Overstreget + + + &Underline + &Understreg + + + Sample + Eksempel + + + Wr&iting System + Skr&ivesystem + + + Select Font + Vælg skrifttype + + + + QFtp + + + Not connected + Ingen forbindelse + + + + Host %1 not found + Vært %1 ikke fundet + + + + Connection refused to host %1 + Forbindelse til vært %1 afvist + + + Connection timed out to host %1 + Forbindelsen timed out til host %1 + + + Connected to host %1 + Tilsluttet vært %1 + + + Connection refused for data connection + Dataforbindelse afvist + + + Unknown error + Ukendt fejl + + + + Connecting to host failed: +%1 + Forbindelse til vært mislykkedes: +%1 + + + + Login failed: +%1 + Login mislykkedes: +%1 + + + + Listing directory failed: +%1 + Opremsning af katalogindhold mislykkedes: +%1 + + + + Changing directory failed: +%1 + Ændring af katalog mislykkedes: +%1 + + + + Downloading file failed: +%1 + Downloading af fil mislykkedes: +%1 + + + + Uploading file failed: +%1 + Uploading af fil mislykkedes: +%1 + + + + Removing file failed: +%1 + Det mislykkedes at fjerne fil: +%1 + + + + Creating directory failed: +%1 + Oprettelse af katalog mislykkedes: +%1 + + + + Removing directory failed: +%1 + Det mislykkedes at fjerne katalog: +%1 + + + Connection closed + Forbindelse lukket + + + Host %1 found + Vært %1 fundet + + + Connection to %1 closed + Forbindelse til %1 lukket + + + Host found + Vært fundet + + + Connected to host + Tilsluttet vært + + + + QHostInfo + + + Unknown error + Ukendt fejl + + + + QHostInfoAgent + + Host not found + Vært ikke fundet + + + Unknown address type + Ukendt adressetype + + + Unknown error + Ukendt fejl + + + + QHttp + + Unknown error + Ukendt fejl + + + Request aborted + Forespørgsel blev annulleret + + + + No server set to connect to + Ingen server at forbinde til + + + + Wrong content length + Forkert indholdslængde + + + + Server closed connection unexpectedly + Serveren afsluttede uventet forbindelsen + + + Error writing response to device + Skrivefejl mens der blev skrevet til enheden + + + + Connection refused + Forbindelse afvist + + + + Host %1 not found + Vært %1 ikke fundet + + + + HTTP request failed + HTTP anmodning mislykkedes + + + + Invalid HTTP response header + Ugyldig HTTP-svar-header + + + Invalid HTTP chunked body + Ugyldig HTTP chunked body + + + + Host %1 found + Vært %1 fundet + + + Connected to host %1 + Tilsluttet vært %1 + + + Connection to %1 closed + Forbindelse til %1 lukket + + + Host found + Vært fundet + + + Connected to host + Tilsluttet vært + + + + Connection closed + Forbindelse lukket + + + Proxy authentication required + Kræver proxy-autentificering + + + Authentication required + Autentificering pĂ¥krævet + + + Connection refused (or timed out) + Forbindelse blev afvist (eller tid udløb) + + + + Proxy requires authentication + Proxy kræver autentificering + + + Host requires authentication + Vært kræver autentificering + + + Data corrupted + Data er ødelagt + + + Unknown protocol specified + En ukendt protokol blev angivet + + + SSL handshake failed + SSL handshake mislykkedes + + + HTTPS connection requested but SSL support not compiled in + Der blevet anmodet om en HTTPS-forbindelse, men SSL understøttelse er ikke kompileret ind + + + + QHttpSocketEngine + + Did not receive HTTP response from proxy + Modtog ikke HTTP-svar fra proxy + + + Error parsing authentication request from proxy + Fejl under fortolking af autentificeringsanmodning fra proxy + + + Authentication required + Autentificering pĂ¥krævet + + + Proxy denied connection + Proxy nægtede forbindelse + + + Error communicating with HTTP proxy + Fejl under kommunikation med HTTP-proxy + + + Proxy server not found + Proxy-server kunne ikke findes + + + Proxy connection refused + Proxy-forbindelse nægtede + + + Proxy server connection timed out + Proxy-serverforbindelse timed out + + + Proxy connection closed prematurely + Proxy-forbindelse afsluttede i utide + + + + QIBaseDriver + + + Error opening database + Der opstod fejl ved Ă¥bning af database + + + Could not start transaction + Kunne ikke pĂ¥begynde transaktionen + + + Unable to commit transaction + Kunne ikke gennemføre transaktionen + + + Unable to rollback transaction + Kunne ikke tilbagetrække transaktionen + + + + QIBaseResult + + Unable to create BLOB + Kunne ikke oprette BLOB + + + Unable to write BLOB + Kunne ikke skrive BLOB + + + Unable to open BLOB + Kunne ikke Ă¥bne BLOB + + + Unable to read BLOB + Kunne ikke læse BLOB + + + Could not find array + Kunne ikke finde array + + + Could not get array data + Kunne ikke hente arraydata + + + Could not get query info + Kunne ikke hente forespørgselsinfo + + + Could not start transaction + Kunne ikke pĂ¥begynde transaktionen + + + Unable to commit transaction + Kunne ikke gennemføre transaktionen + + + Could not allocate statement + Kunne ikke allokere statement + + + Could not prepare statement + Kunne ikke forberede udsagn + + + Could not describe input statement + Kunne ikke beskrive input-statement + + + Could not describe statement + Kunne ikke beskrive statement + + + Unable to close statement + Kunne ikke lukke udsagn + + + Unable to execute query + Kunne ikke udføre forespørgsel + + + Could not fetch next item + Kunne ikke hente næste element + + + Could not get statement info + Kunne ikke hente udsagnsinformation + + + + QIODevice + + + Permission denied + Tilladelse nægtet + + + Too many open files + Der er for mange Ă¥bne filer + + + No such file or directory + Fil eller katalog findes ikke + + + No space left on device + Ingen plads tilbage pĂ¥ enheden + + + + Unknown error + Ukendt fejl + + + + QInputContext + + + XIM + + + + XIM input method + XIM input-metode + + + Windows input method + Windows input-metode + + + Mac OS X input method + Mac OS X input-metode + + + + QInputDialog + + + Enter a value: + Indtast en værdi: + + + + QLibrary + + + Could not mmap '%1': %2 + + + + Plugin verification data mismatch in '%1' + Plugin-verifikationsdata er sat forkert sammen i '%1' + + + Could not unmap '%1': %2 + Der var ikke muligt at lave unmap pĂ¥ '%1': %2 + + + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] + Plugin '%1' bruger inkompatibelt Qt-bibliotek. (%2.%3.%4) [%5] + + + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" + Plugin '%1' bruger inkompatibelt Qt-bibliotek. Forventet build key "%2", hentede "%3"' + + + Unknown error + Ukendt fejl' + + + + The shared library was not found. + DSO blev ikke fundet. + + + The file '%1' is not a valid Qt plugin. + Filen '%1' er ikke et gyldigt Qt-plugin. + + + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) + Plugin '%1' bruger inkompatibelt Qt-bibliotek. (Ikke muligt at mikse debug og release-biblioteker) + + + + Cannot load library %1: %2 + Kan ikke indlæse bibliotek %1: %2 + + + + Cannot unload library %1: %2 + Kan ikke afregistrere bibliotek %1: %2 + + + + Cannot resolve symbol "%1" in %2: %3 + Kan ikke løse symbol "%1" i %2: %3 + + + + QLineEdit + + + &Undo + &Fortryd + + + &Redo + &Gendan + + + Cu&t + K&lip + + + &Copy + &KopiĂ©r + + + &Paste + &Sæt ind + + + Delete + Slet + + + Select All + MarkĂ©r alt + + + + QLocalServer + + + %1: Name error + %1: Navnefejl + + + %1: Permission denied + %1: Tilladelse nægtet + + + %1: Address in use + %1: Adresse i brug + + + + %1: Unknown error %2 + %1: Ukendt fejl %2 + + + + QLocalSocket + + + %1: Connection refused + %1: Forbindelse afvist + + + + %1: Remote closed + %1: Den anden ende lukkede + + + %1: Invalid name + %1: Ugyldigt navn + + + + %1: Socket access error + %1: Fejl i socket-adgang + + + + %1: Socket resource error + %1: Fejl i socket-ressource + + + + %1: Socket operation timed out + %1: Socket-handling timed out + + + + %1: Datagram too large + %1: Datagram er for stort + + + %1: Connection error + %1: Forbindelsesfejl + + + + %1: The socket operation is not supported + %1: Socket-handlingen understøttes ikke + + + %1: Unknown error + %1: Ukendt fejl + + + + %1: Unknown error %2 + %1: Ukendt fejl %2 + + + + QMYSQLDriver + + + Unable to open database ' + Kunne ikke Ă¥bne databasen ' + + + Unable to connect + Kunne ikke forbinde + + + Unable to begin transaction + Kunne ikke pĂ¥begynde transaktionen + + + Unable to commit transaction + Kunne ikke gennemføre transaktionen + + + Unable to rollback transaction + Kunne ikke tilbagetrække transaktionen + + + + QMYSQLResult + + Unable to fetch data + Kunne ikke hente data + + + Unable to execute query + Kunne ikke udføre forespørgsel + + + Unable to store result + Kunne ikke gemme resultatet + + + Unable to prepare statement + Kunne ikke forberede udsagn + + + Unable to reset statement + Kunne ikke nulstille udsagn + + + Unable to bind value + Kunne ikke tildele værdi + + + Unable to execute statement + Kunne ikke udføre udsagn + + + Unable to bind outvalues + Kunne ikke binde udværdier + + + Unable to store statement results + Kunne ikke gemme udsagnsresultater + + + Unable to execute next query + Kunne ikke udføre næste forespørgsel + + + Unable to store next result + Kunne ikke gemme næste resultat + + + + QMdiArea + + + (Untitled) + (Uden titel) + + + + QMdiSubWindow + + + %1 - [%2] + + + + Close + Luk + + + Minimize + MinimĂ©r + + + Restore Down + Gendan Ned + + + &Restore + &Gendan + + + &Move + &Flyt + + + &Size + &Størrelse + + + Mi&nimize + Mi&nimĂ©r + + + Ma&ximize + Ma&ksimĂ©r + + + Stay on &Top + Bliv &oppe + + + &Close + &Luk + + + - [%1] + + + + Maximize + MaksimĂ©r + + + Unshade + Fjern skygge + + + Shade + Skygge + + + Restore + Gendan + + + Help + Hjælp + + + Menu + + + + + QMenu + + Close + Luk + + + Open + Ă…bn + + + Execute + Udfør + + + + QMessageBox + + Help + Hjælp + + + OK + + + + About Qt + Om Qt + + + <p>This program uses Qt version %1.</p> + <p>Dette program bruger Qt-version %1.</p> + + + Show Details... + Vis detaljer... + + + Hide Details... + Skjul detaljer... + + + <h3>About Qt</h3>%1<p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is a Nokia product. See <a href="http://qtsoftware.com/qt/">qtsoftware.com/qt/</a> for more information.</p> + <h3>Om Qt</h3>%1<p>Qt er et C++ toolkit til cross-platform applikationsudvikling.</p><p>Qt tilbyder single-source portabilitet til MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, og alle større kommercielle Unix-varianter. Qt er ogsĂ¥ tilgængeligt til indlejrede systemer som Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt er et Nokia produkt. Se <a href="http://qtsoftware.com/qt/">qtsoftware.com/qt/</a> for yderligere information.</p> + + + <p>This program uses Qt Open Source Edition version %1.</p><p>Qt Open Source Edition is intended for the development of Open Source applications. You need a commercial Qt license for development of proprietary (closed source) applications.</p><p>Please see <a href="http://qtsoftware.com/company/model/">qtsoftware.com/company/model/</a> for an overview of Qt licensing.</p> + <p>Dette program bruger Qt Open Source Edition version %1.</p><p>Qt Open Source Edition er beregnet til udvikling af Open Source applikationer. En kommerciel Qt licens er nødvendig til udvikling af proprietære (lukket sourcekode) applikationer.</p><p>Se venligst <a href="http://qtsoftware.com/company/model/">qtsoftware.com/company/model/</a> for et overblik over Qt licensforhold.</p> + + + + QMultiInputContext + + + Select IM + MarkĂ©r IM + + + + QMultiInputContextPlugin + + + Multiple input method switcher + Multiple input metode-switcher + + + Multiple input method switcher that uses the context menu of the text widgets + Multiple input metode-switcher, der benytter tekstkontrollernes kontekstmenuer + + + + QNativeSocketEngine + + + The remote host closed the connection + Fjern-hosten lukkede forbindelsen + + + Network operation timed out + Netværksoperationen timed out + + + Out of resources + Ikke flere ressourcer + + + Unsupported socket operation + Socket-operation ikke understøttet + + + Protocol type not supported + Protokoltypen understøttes ikke + + + Invalid socket descriptor + Ugyldig socket-deskriptor + + + Network unreachable + Netværket er ikke tilgængeligt + + + Permission denied + Tilladelse nægtet + + + Connection timed out + Forbindelsen timed out + + + Connection refused + Forbindelse afvist + + + The bound address is already in use + Den bundne adresse er allerede i brug + + + The address is not available + Adressen er ikke tilgængelig + + + The address is protected + Adressen er beskyttet + + + Unable to send a message + Kunne ikke sende en besked + + + Unable to receive a message + Kunne ikke modtage en besked + + + Unable to write + Kunne ikke skrive + + + Network error + Netværksfejl + + + Another socket is already listening on the same port + En anden socket lytter allerede pĂ¥ samme port + + + Unable to initialize non-blocking socket + Kunne ikke initialisere non-blocking socket + + + Unable to initialize broadcast socket + Kunne ikke initialisere broadcast-socket + + + Attempt to use IPv6 socket on a platform with no IPv6 support + Forsøg pĂ¥ at bruge IPv6-socket pĂ¥ en platform uden IPv6-support + + + Host unreachable + Vært er ikke tilgængelig + + + Datagram was too large to send + Datagrammet var for stort til at blive sendt + + + Operation on non-socket + Handling pĂ¥ non-socket + + + Unknown error + Ukendt fejl + + + The proxy type is invalid for this operation + Proxytypen er ugyldig til denne handling + + + + QNetworkAccessCacheBackend + + + Error opening %1 + Der opstod fejl i at Ă¥bne %1 + + + + QNetworkAccessFileBackend + + + Request for opening non-local file %1 + Anmodning om at Ă¥bne ikke-lokal fil %1 + + + Error opening %1: %2 + Der opstod fejl i at Ă¥bne %1: %2 + + + Write error writing to %1: %2 + Skrivefejl mens der blev skrevet til %1: %2 + + + Cannot open %1: Path is a directory + Kan ikke Ă¥bne %1: Stien er et katalog + + + Read error reading from %1: %2 + Læsefejl mens der blev læst fra %1: %2 + + + + QNetworkAccessFtpBackend + + + No suitable proxy found + Ingen passende proxy blev fundet + + + Cannot open %1: is a directory + Kan ikke Ă¥bne %1: Er et katalog + + + Logging in to %1 failed: authentication required + Der opstod fejl i at logge pĂ¥ %1: Autentificering kræves + + + Error while downloading %1: %2 + Der opstod fejl i at downloade %1: %2 + + + Error while uploading %1: %2 + Der opstod fejl i at uploade %1: %2 + + + + QNetworkAccessHttpBackend + + + No suitable proxy found + Ingen passende proxy blev fundet + + + + QNetworkReply + + Error downloading %1 - server replied: %2 + Der opstod fejl i at downloade %1 - serveren svarede: %2 + + + + Protocol "%1" is unknown + Protokollen "%1" er ukendt + + + + QNetworkReplyImpl + + Operation canceled + Handling blev annulleret + + + + QOCIDriver + + + Unable to logon + Kunne ikke logge pĂ¥ + + + Unable to initialize + QOCIDriver + Kunne ikke initialisere + + + Unable to begin transaction + Kunne ikke pĂ¥begynde transaktionen + + + Unable to commit transaction + Kunne ikke gennemføre transaktionen + + + Unable to rollback transaction + Kunne ikke tilbagetrække transaktionen + + + + QOCIResult + + Unable to bind column for batch execute + Kunne ikke tildele kolonne til batch-udførsel + + + Unable to execute batch statement + Kunne ikke udføre batch-udsagn + + + Unable to goto next + Kunne ikke gĂ¥ til den næste + + + Unable to alloc statement + Kunne ikke allokere udsagn + + + Unable to prepare statement + Kunne ikke forberede udsagn + + + Unable to bind value + Kunne ikke tildele værdi + + + Unable to execute select statement + Kunne ikke udføre det valgte udsagn + + + Unable to execute statement + Kunne ikke udføre udsagn + + + + QODBCDriver + + + Unable to connect + Kunne ikke forbinde + + + Unable to connect - Driver doesn't support all needed functionality + Kunne ikke forbinde. Driveren understøtter ikke alle de nødvendige funktionaliteter + + + Unable to disable autocommit + Kunne ikke slĂ¥ auto-udfør fra + + + Unable to commit transaction + Kunne ikke gennemføre transaktionen + + + Unable to rollback transaction + Kunne ikke tilbagetrække transaktionen + + + Unable to enable autocommit + Kunne ikke slĂ¥ auto-udfør til + + + + QODBCResult + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration + QODBCResult::reset: Kunne ikke indstille 'SQL_CURSOR_STATIC' til udsagnsattribut. KontrollĂ©r ODBC-driver-konfigurationen + + + Unable to execute statement + Kunne ikke udføre udsagn + + + Unable to fetch next + Kunne ikke hente den næste + + + Unable to prepare statement + Kunne ikke forberede udsagn + + + Unable to bind variable + Kunne ikke tildele variabel + + + Unable to fetch last + Kunne ikke hente den sidste + + + Unable to fetch + Kunne ikke hente + + + Unable to fetch first + Kunne ikke hente den første + + + Unable to fetch previous + Kunne ikke hente den forrige + + + + QObject + + + Home + Hjem + + + + Operation not supported on %1 + Handling blev ikke understøttet pĂ¥ %1 + + + Invalid URI: %1 + Ugyldig URI: %1 + + + + Write error writing to %1: %2 + Skrivefejl mens der blev skrevet til %1: %2 + + + Read error reading from %1: %2 + Læsefejl mens der blev læst fra %1: %2 + + + Socket error on %1: %2 + Socket-fejl pĂ¥ %1: %2 + + + Remote host closed the connection prematurely on %1 + Fjern-host lukkede forbindelsen for tidligt pĂ¥ %1 + + + Protocol error: packet of size 0 received + Protokolfejl: Pakke pĂ¥ størrelsen 0 modtaget + + + No host name given + Hostnavn mangler + + + + QPPDOptionsModel + + + Name + Navn + + + Value + Værdi + + + + QPSQLDriver + + + Unable to connect + Kunne ikke skabe forbindelse + + + Could not begin transaction + Kunne ikke pĂ¥begynde transaktion + + + Could not commit transaction + Kunne ikke gennemføre transaktion + + + Could not rollback transaction + Kunne ikke tilbagetrække transaktion + + + Unable to subscribe + Kunne ikke tilmelde + + + Unable to unsubscribe + Kunne ikke afmelde + + + + QPSQLResult + + Unable to create query + Kunne ikke oprette forespørgsel + + + Unable to prepare statement + Kunne ikke forberede udsagn + + + + QPageSetupWidget + + + Centimeters (cm) + Centimeter (cm) + + + Millimeters (mm) + Millimeter (mm) + + + Inches (in) + + + + Points (pt) + Point (pt) + + + Form + + + + Paper + Papir + + + Page size: + Sidestørrelse: + + + Width: + Vidde: + + + Height: + Højde: + + + Paper source: + Papirkilde: + + + Orientation + + + + Portrait + Portræt + + + Landscape + Landskab + + + Reverse landscape + Omvendt landskab + + + Reverse portrait + Omvendt portræt + + + Margins + Margener + + + top margin + Margen - øverst + + + left margin + Margen - venstre + + + right margin + Margen - højre + + + bottom margin + Margen - bund + + + + QPluginLoader + + + Unknown error + Ukendt fejl + + + The plugin was not loaded. + Plugin blev ikke indlæst. + + + + QPrintDialog + + + locally connected + lokalt forbundet + + + Aliases: %1 + Aliasser: %1 + + + unknown + Ukendt + + + + A0 (841 x 1189 mm) + + + + A1 (594 x 841 mm) + + + + A2 (420 x 594 mm) + + + + A3 (297 x 420 mm) + + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + + + + A5 (148 x 210 mm) + + + + A6 (105 x 148 mm) + + + + A7 (74 x 105 mm) + + + + A8 (52 x 74 mm) + + + + A9 (37 x 52 mm) + + + + B0 (1000 x 1414 mm) + + + + B1 (707 x 1000 mm) + + + + B2 (500 x 707 mm) + + + + B3 (353 x 500 mm) + + + + B4 (250 x 353 mm) + + + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + + + + B6 (125 x 176 mm) + + + + B7 (88 x 125 mm) + + + + B8 (62 x 88 mm) + + + + B9 (44 x 62 mm) + + + + B10 (31 x 44 mm) + + + + C5E (163 x 229 mm) + + + + DLE (110 x 220 mm) + + + + Executive (7.5 x 10 inches, 191 x 254 mm) + + + + Folio (210 x 330 mm) + + + + Ledger (432 x 279 mm) + + + + Legal (8.5 x 14 inches, 216 x 356 mm) + + + + Letter (8.5 x 11 inches, 216 x 279 mm) + + + + Tabloid (279 x 432 mm) + + + + US Common #10 Envelope (105 x 241 mm) + + + + + OK + + + + Print + Udskriv + + + Print To File ... + Udskriv til fil... + + + + Print range + UdskriftsomrĂ¥de + + + Print all + Udskriv alle + + + + File %1 is not writable. +Please choose a different file name. + Filen %1 kan ikke skrives. +Vælg et andet filnavn. + + + %1 already exists. +Do you want to overwrite it? + %1 findes allerede. +Ă˜nsker du at overskrive? + + + File exists + Fil findes + + + <qt>Do you want to overwrite it?</qt> + <qt>Ă˜nsker du at overskrive?</qt> + + + Print selection + Udskriv markerede + + + %1 is a directory. +Please choose a different file name. + %1 er et katalog. +Vælg et andet filnavn. + + + A0 + + + + A1 + + + + A2 + + + + A3 + + + + A4 + + + + A5 + + + + A6 + + + + A7 + + + + A8 + + + + A9 + + + + B0 + + + + B1 + + + + B2 + + + + B3 + + + + B4 + + + + B5 + + + + B6 + + + + B7 + + + + B8 + + + + B9 + + + + B10 + + + + C5E + + + + DLE + + + + Executive + + + + Folio + + + + Ledger + + + + Legal + + + + Letter + + + + Tabloid + + + + US Common #10 Envelope + + + + Custom + Brugerdefineret + + + &Options >> + &Indstillinger>> + + + &Print + &Udskriv + + + &Options << + &Indstillinger<< + + + Print to File (PDF) + Udskriv til fil (PDF) + + + Print to File (Postscript) + Udskriv til fil (Postscript) + + + Local file + Lokal fil + + + Write %1 file + Skriv %1 fil + + + + The 'From' value cannot be greater than the 'To' value. + 'Fra'-værdien kan ikke være større end 'til'-værdien. + + + + QPrintPreviewDialog + + Page Setup + Sideopsætning + + + + %1% + + + + Print Preview + Vis udskrift + + + Next page + Næste side + + + Previous page + Forrige side + + + First page + Første side + + + Last page + Sidste side + + + Fit width + Tilpas bredde + + + Fit page + Tilpas siden + + + Zoom in + Zoom ind + + + Zoom out + Zoom ud + + + Portrait + Portræt + + + Landscape + Landskab + + + Show single page + Vis enkelt side + + + Show facing pages + Vis sideopslag + + + Show overview of all pages + Vis oversigt af alle sider + + + Print + Udskriv + + + Page setup + Sideopsætning + + + Close + Luk + + + Export to PDF + EksportĂ©r til PDF + + + Export to PostScript + EksportĂ©r til PostScript + + + + QPrintPropertiesWidget + + Form + Form + + + Page + Side + + + Advanced + Avanceret + + + + QPrintSettingsOutput + + Form + + + + Copies + Kopier + + + Print range + Udskriv sider + + + Print all + Udskriv alle + + + Pages from + Sider fra + + + to + til + + + Selection + Valg + + + Output Settings + Udskriftsindstillinger + + + Copies: + Kopier: + + + Collate + Samordne + + + Reverse + Omvendt + + + Options + Valgmuligheder + + + Color Mode + Farvetilstand + + + Color + Farve + + + Grayscale + GrĂ¥skala + + + Duplex Printing + Dobbelsidet + + + None + Ingen + + + Long side + Bog + + + Short side + Tavle + + + + QPrintWidget + + Form + + + + Printer + ' + + + &Name: + &Navn: + + + P&roperties + &Egenskaber + + + Location: + Placering: + + + Preview + Vis udskrift + + + Type: + + + + Output &file: + Udskrifts&fil: + + + ... + + + + + QProcess + + + Could not open input redirection for reading + Kunne ikke Ă¥bne input redirection for læsning + + + + Could not open output redirection for writing + Kunne ikke Ă¥bne output redirection for skrivning + + + Resource error (fork failure): %1 + Ressource fejl (fork fejl): %1 + + + Process operation timed out + Proces-operation time out + + + Error reading from process + Fejl ved læsning fra proces + + + + Error writing to process + Fejl ved skrivning til proces + + + Process crashed + Proces crashede + + + Process failed to start + Processen kunne ikke starte + + + + QProgressDialog + + + Cancel + Annuller + + + + QPushButton + + Open + Ă…bn + + + + QRadioButton + + Check + KontrollĂ©r + + + + QRegExp + + + no error occurred + der opstod ingen fejl + + + disabled feature used + deaktiveret funktion blev brugt + + + bad char class syntax + dĂ¥rlig char class syntaks + + + bad lookahead syntax + dĂ¥rlig lookahead syntaks + + + bad repetition syntax + dĂ¥rlig gentagelsessyntaks + + + invalid octal value + ugyldigt oktal-tal + + + missing left delim + Manglende venstre delimiter + + + unexpected end + uventet afslutning + + + met internal limit + nĂ¥ede interne grænse + + + + QSQLite2Driver + + + Error to open database + Der opstod fejl ved Ă¥bning af database + + + Unable to begin transaction + Kunne ikke pĂ¥begynde transaktionen + + + Unable to commit transaction + Kunne ikke gennemføre transaktionen + + + Unable to rollback Transaction + Kunne ikke tilbagetrække transaktion + + + + QSQLite2Result + + Unable to fetch results + Kunne ikke hente resultater + + + Unable to execute statement + Kunne ikke udføre statement + + + + QSQLiteDriver + + + Error opening database + Der opstod fejl ved Ă¥bning af database + + + Error closing database + Der opstod fejl ved lukning af database + + + Unable to begin transaction + Kunne ikke pĂ¥begynde transaktionen + + + Unable to commit transaction + Kunne ikke gennemføre transaktion + + + Unable to rollback transaction + Kunne ikke tilbagetrække transaktion + + + + QSQLiteResult + + Unable to fetch row + Kunne ikke hente række + + + Unable to execute statement + Kunne ikke udføre udsagn + + + Unable to reset statement + Kunne ikke nulstille udsagn + + + Unable to bind parameters + Unable to bind parameters + + + Parameter count mismatch + Misforhold i parametertælling + + + No query + Ingen forespørgesel + + + + QScrollBar + + + Scroll here + Scroll her + + + Left edge + Venstre kant + + + Top + Ă˜verst + + + Right edge + Højre kant + + + Bottom + Bund + + + Page left + Side venstre + + + + Page up + Side øverst + + + Page right + Side højre + + + + Page down + Side ned + + + Scroll left + Scroll til venstre + + + Scroll up + Scroll op + + + Scroll right + Scroll til højre + + + Scroll down + Scroll ned + + + Line up + Linie op + + + Position + Placering + + + Line down + Linie ned + + + + QSharedMemory + + + %1: unable to set key on lock + %1: Kunne ikke oprette nøgle + + + %1: create size is less then 0 + %1: create size is less then 0 + + + + %1: unable to lock + %1: Kunne ikke lĂ¥se + + + %1: unable to unlock + %1: Kunne ikke oprette nøgle + + + + %1: permission denied + %1: Tilladelse nægtet + + + %1: already exists + %1: Findes allerede + + + + %1: doesn't exists + %1: Findes ikke + + + + %1: out of resources + %1: Ikke flere ressourcer + + + + %1: unknown error %2 + %1: ukendt fejl %2 + + + %1: key is empty + %1: nøgle er tom + + + %1: unix key file doesn't exists + %1: Kunne ikke oprette nøgle + + + %1: ftok failed + %1: ftok mislykkedes + + + + %1: unable to make key + %1: Kunne ikke oprette nøgle + + + %1: system-imposed size restrictions + %1: System-pĂ¥lagte størrelsesrestriktioner + + + %1: not attached + %1: Ikke vedhæftet + + + %1: invalid size + %1: Ugyldig størrelse + + + %1: key error + %1: Nøglefejl + + + %1: size query failed + %1: Størrelsesforespørgsel mislykkedes + + + + QShortcut + + + Space + + + + Esc + + + + Tab + + + + Backtab + Tilbage-tabulator + + + Backspace + Tilbage + + + Return + + + + Enter + + + + Ins + + + + Del + + + + Pause + + + + Print + Udskriv + + + SysReq + + + + Home + + + + End + + + + Left + Venstre + + + Up + Op + + + Right + Højre + + + Down + Ned + + + PgUp + + + + PgDown + + + + CapsLock + ' + + + NumLock + + + + ScrollLock + + + + Menu + + + + Help + Hjælp + + + Back + Tilbage + + + Forward + Frem + + + Stop + + + + Refresh + Opdater + + + Volume Down + Lydstyrke ned + + + Volume Mute + Lydstyrke mute + + + Volume Up + Lydstyrke op + + + Bass Boost + + + + Bass Up + Bass op + + + Bass Down + Bass ned + + + Treble Up + Diskant op + + + Treble Down + Diskant ned + + + Media Play + + + + Media Stop + + + + Media Previous + Media forrige + + + Media Next + Media næste + + + Media Record + + + + Favorites + + + + Search + Søg + + + Standby + + + + Open URL + Ă…bn URL + + + Launch Mail + Start mail + + + Launch Media + Start Media + + + Launch (0) + Start (0) + + + Launch (1) + Start (1) + + + Launch (2) + Start (2) + + + Launch (3) + Start (3) + + + Launch (4) + Start (4) + + + Launch (5) + Start (5) + + + Launch (6) + Start (6) + + + Launch (7) + Start (7) + + + Launch (8) + Start (8) + + + Launch (9) + Start (9) + + + Launch (A) + Start (A) + + + Launch (B) + Start (B) + + + Launch (C) + Start (C) + + + Launch (D) + Start (D) + + + Launch (E) + Start (E) + + + Launch (F) + Start (F) + + + Print Screen + + + + Page Up + + + + Page Down + + + + Caps Lock + + + + Num Lock + + + + Number Lock + + + + Scroll Lock + + + + Insert + + + + Delete + + + + Escape + + + + System Request + + + + Select + Væg + + + Yes + Ja + + + No + Nej + + + Context1 + Kontekst1 + + + Context2 + Kontekst2 + + + Context3 + Kontekst3 + + + Context4 + Kontekst4 + + + Call + Ring til + + + Hangup + Læg pĂ¥ + + + Flip + Vend + + + Ctrl + + + + Shift + + + + Alt + + + + Meta + + + + + + + + + F%1 + + + + Home Page + Startside + + + + QSlider + + + Page left + Side venstre + + + Page up + Side op + + + Position + Placering + + + Page right + Side højre + + + Page down + Side ned + + + + QSocks5SocketEngine + + Connection to proxy refused + Proxy-forbindelse nægtede + + + Connection to proxy closed prematurely + Proxy-forbindelse afsluttede i utide + + + Proxy host not found + Proxy-host kunne ikke findes + + + Connection to proxy timed out + Proxy-serverforbindelse timed out + + + Proxy authentication failed + Proxy autentificering mislykkedes + + + Proxy authentication failed: %1 + Proxy autentificering mislykkedes: %1 + + + SOCKS version 5 protocol error + SOCKS version 5 protokolfejl + + + General SOCKSv5 server failure + General SOCKSv5 serverfejl + + + Connection not allowed by SOCKSv5 server + Forbindelse ikke tilladt a SOCKSv5-server + + + TTL expired + TTL udløbet + + + SOCKSv5 command not supported + SOCKSv5-kommando ikke understøttet + + + Address type not supported + Adressetype understøttes ikke + + + Unknown SOCKSv5 proxy error code 0x%1 + Ukendt SOCKSv5 proxy fejlkode 0x%1 + + + Network operation timed out + Netværksoperationen timed out + + + + QSpinBox + + More + Mere + + + Less + Mindre + + + + QSql + + + Delete + Slet + + + Delete this record? + Slet denne post? + + + Yes + Ja + + + No + Nej + + + Insert + Indsæt + + + Update + Opdater + + + Save edits? + Gem ændringer? + + + Cancel + Annuller + + + Confirm + Bekræft + + + Cancel your edits? + Skal dine ændringer annulleres? + + + + QSslSocket + + + Unable to write data: %1 + Kunne ikke skrive data: %1 + + + Error while reading: %1 + Der opstod en fejl under læsning af: %1 + + + Error during SSL handshake: %1 + Der opstod en fejl under SSL handshake: %1 + + + Error creating SSL context (%1) + Der opstod fejl under oprettelse af SSL-kontekst (%1) + + + Invalid or empty cipher list (%1) + Ugyldig eller tom chifferliste (%1) + + + Error creating SSL session, %1 + Der opstod fejl under oprettelse af SSL-session, %1 + + + Error creating SSL session: %1 + Der opstod fejl under oprettelse af SSL-session, %1 + + + Cannot provide a certificate with no key, %1 + Kan ikke give et certifikat uden nøgle, %1 + + + Error loading local certificate, %1 + Der opstod fejl under indlæsning af lokalt certifikat, %1 + + + Error loading private key, %1 + Der opstod fejl under indlæsning af privat nøgle, %1 + + + Private key does not certificate public key, %1 + Privat-nøgle autoriserer ikke offentlig-nøgle, %1 + + + + QSystemSemaphore + + + %1: out of resources + %1: Ikke flere ressourcer + + + + %1: permission denied + %1: Tilladelse nægtet + + + %1: already exists + %1: Findes allerede + + + %1: does not exist + %1: Findes ikke + + + + %1: unknown error %2 + %1: Ukendt fejl %2 + + + + QTDSDriver + + + Unable to open connection + Kunne ikke etablere forbindelsen + + + Unable to use database + Kunne ikke bruge databasen + + + + QTabBar + + Scroll Left + Scroll til venstre + + + Scroll Right + Scroll til højre + + + + QTcpServer + + + Operation on socket is not supported + Socket-operation ikke understøttet + + + + QTextControl + + + &Undo + &Fortryd + + + &Redo + &Gendan + + + Cu&t + K&lip + + + &Copy + &KopiĂ©r + + + Copy &Link Location + KopiĂ©r l&ink + + + &Paste + &Sæt ind + + + Delete + Slet + + + Select All + MarkĂ©r alt + + + + QToolButton + + Press + Tryk pĂ¥ + + + Open + Ă…bn + + + + QUdpSocket + + + This platform does not support IPv6 + Denne platform understøtter ikke IPv6 + + + + QUndoGroup + + + Undo + Fortryd + + + Redo + Gendan + + + + QUndoModel + + + <empty> + <tom> + + + + QUndoStack + + + Undo + Fortryd + + + Redo + Gendan + + + + QUnicodeControlCharacterMenu + + + LRM Left-to-right mark + + + + RLM Right-to-left mark + + + + ZWJ Zero width joiner + + + + ZWNJ Zero width non-joiner + + + + ZWSP Zero width space + + + + LRE Start of left-to-right embedding + + + + RLE Start of right-to-left embedding + + + + LRO Start of left-to-right override + + + + RLO Start of right-to-left override + + + + PDF Pop directional formatting + + + + Insert Unicode control character + + + + + QWebFrame + + + Request cancelled + Anmodning annulleret + + + Request blocked + Anmodning blokeret + + + Cannot show URL + Kan ikke vise URL + + + Frame load interruped by policy change + Billedindlæsning afbrudt af ændringer i retningslinier + + + Cannot show mimetype + Kan ikke vise MIME-type + + + File does not exist + Filen findes ikke + + + + QWebPage + + + Bad HTTP request + DĂ¥rlig HTTP-anmodning + + + + Submit + default label for Submit buttons in forms on web pages + Send + + + Submit + Submit (input element) alt text for <input> elements with no alt, title, or value + Send + + + Reset + default label for Reset buttons in forms on web pages + Nulstil + + + This is a searchable index. Enter search keywords: + text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' + Dette er et søgeindeks. Indtast søgeord: + + + Choose File + title for file button used in HTML forms + Vælg fil + + + No file selected + text to display in file button used in HTML forms when no file is selected + Der er ikke valgt en fil + + + Open in New Window + Open in New Window context menu item + Ă…bn i nyt vindue + + + Save Link... + Download Linked File context menu item + Gem link... + + + Copy Link + Copy Link context menu item + KopiĂ©r link + + + Open Image + Open Image in New Window context menu item + Ă…bn billede + + + Save Image + Download Image context menu item + Gem billede + + + Copy Image + Copy Link context menu item + KopiĂ©r billede + + + Open Frame + Open Frame in New Window context menu item + Ă…bn faneblad + + + Copy + Copy context menu item + KopiĂ©r + + + Go Back + Back context menu item + GĂ¥ tilbage + + + Go Forward + Forward context menu item + GĂ¥ frem + + + Stop + Stop context menu item + Stop + + + Reload + Reload context menu item + Genindlæs + + + Cut + Cut context menu item + Klip + + + Paste + Paste context menu item + Sæt ind + + + No Guesses Found + No Guesses Found context menu item + Der er ikke fundet nogen gæt + + + Ignore + Ignore Spelling context menu item + IgnorĂ©r + + + Add To Dictionary + Learn Spelling context menu item + Tilføj til ordbog + + + Search The Web + Search The Web context menu item + Søg pĂ¥ nettet + + + Look Up In Dictionary + Look Up in Dictionary context menu item + SlĂ¥ op i ordbog + + + Open Link + Open Link context menu item + Ă…bn link + + + Ignore + Ignore Grammar context menu item + IgnorĂ©r + + + Spelling + Spelling and Grammar context sub-menu item + Stavekontrol + + + Show Spelling and Grammar + menu item title + Vis stave- og grammatikkontrol + + + Hide Spelling and Grammar + menu item title + Skjul stave- og grammatikkontrol + + + Check Spelling + Check spelling context menu item + Kør stavekontrol + + + Check Spelling While Typing + Check spelling while typing context menu item + Kør stavekontrol mens der tastes + + + Check Grammar With Spelling + Check grammar with spelling context menu item + Kør grammatikkontrol sammen med stavekontrol + + + Fonts + Font context sub-menu item + Skrifttyper + + + Bold + Bold context menu item + Fed + + + Italic + Italic context menu item + Kursiv + + + Underline + Underline context menu item + Understreget + + + Outline + Outline context menu item + Kontur + + + Direction + Writing direction context sub-menu item + Retning + + + Text Direction + Text direction context sub-menu item + Tekstretning + + + Default + Default writing direction context menu item + Standard + + + LTR + Left to Right context menu item + + + + RTL + Right to Left context menu item + + + + Inspect + Inspect Element context menu item + InspicĂ©r + + + No recent searches + Label for only item in menu that appears when clicking on the search field image, when no searches have been performed + Ingen aktuelle søgninger + + + Recent searches + label for first item in the menu that appears when clicking on the search field image, used as embedded menu title + Aktuelle søgninger + + + Clear recent searches + menu item in Recent Searches menu that empties menu's contents + Ryd aktuelle søgninger + + + Unknown + Unknown filesize FTP directory listing item + Ukendt + + + %1 (%2x%3 pixels) + Title string for images + %1 (%2x%3 pixels) + + + + Web Inspector - %2 + Web-inspektør - %2 + + + + Scroll here + Scroll her + + + Left edge + Venstre kant + + + Top + + + + Right edge + Højre kant + + + Bottom + Bund + + + Page left + Side venstre + + + Page up + Side øverst + + + Page right + Side højre + + + Page down + Side ned + + + Scroll left + Scroll til venstre + + + Scroll up + Scroll op + + + Scroll right + Scroll til højre + + + Scroll down + Scroll ned + + + + %n file(s) + number of chosen file + + %n fil + %n filer + + + + + JavaScript Alert - %1 + JavaScript alert - %1 + + + JavaScript Confirm - %1 + JavaScript Bekræft - %1 + + + JavaScript Prompt - %1 + JavaScript Prompt - %1 + + + Move the cursor to the next character + Flyt markør til næste tegn + + + Move the cursor to the previous character + Flyt markør til forrige tegn + + + Move the cursor to the next word + Flyt markør til næste ord + + + Move the cursor to the previous word + Flyt markør til forrige ord + + + Move the cursor to the next line + Flyt markør til næste linie + + + Move the cursor to the previous line + Flyt markør til forrige linie + + + Move the cursor to the start of the line + Flyt markør til starten af linien + + + Move the cursor to the end of the line + Flyt markør til slutningen af linien + + + Move the cursor to the start of the block + Flyt markør til starten af sektionen + + + Move the cursor to the end of the block + Flyt markør til slutningen af sektionen + + + Move the cursor to the start of the document + Flyt markør til starten af dokumentet + + + Move the cursor to the end of the document + Flyt markør til slutningen af dokumentet + + + Select to the next character + Vælg til næste tegn + + + Select to the previous character + Vælg til forrige tegn + + + Select to the next word + Vælg til næste ord + + + Select to the previous word + Vælg til forrige ord + + + Select to the next line + Vælg til næste linie + + + Select to the previous line + Vælg til forrige linie + + + Select to the start of the line + Vælg til starten af linien + + + Select to the end of the line + Vælg til slutningen af linien + + + Select to the start of the block + Vælg til starten af sektionen + + + Select to the end of the block + Vælg til slutningen af sektionen + + + Select to the start of the document + Vælg til starten af dokumentet + + + Select to the end of the document + Vælg til slutningen af dokumentet + + + Delete to the start of the word + Slet til starten af ordet + + + Delete to the end of the word + Slet til slutningen af ordet + + + + QWhatsThisAction + + + What's This? + Hvad er dette? + + + + QWidget + + + * + + + + + QWizard + + + Go Back + GĂ¥ tilbage + + + Continue + Fortsæt + + + Commit + Udfør + + + Done + Færdig + + + Help + Hjælp + + + < &Back + < &Tilbage + + + &Finish + &Afslut + + + Cancel + Annuller + + + &Help + &Hjælp + + + &Next + &Næste + + + &Next > + &Næste > + + + + QWorkspace + + + &Restore + &Gendan + + + &Move + &Flyt + + + &Size + &Størrelse + + + Mi&nimize + Mi&nimĂ©r + + + Ma&ximize + Ma&ksimĂ©r + + + &Close + &Luk + + + Stay on &Top + Bliv pĂ¥ &toppen + + + Sh&ade + Sk&ygge + + + %1 - [%2] + + + + Minimize + Minimer + + + Restore Down + Gendan ned + + + Close + Luk + + + &Unshade + &Fjern skygge + + + + QXml + + + no error occurred + der opstod ingen fejl + + + error triggered by consumer + + + + unexpected end of file + uventet afslutning pĂ¥ fil + + + more than one document type definition + mere end Ă©n definition pĂ¥ dokumenttype + + + error occurred while parsing element + der opstod fejl under fortolking af element + + + tag mismatch + + + + error occurred while parsing content + der opstod fejl under fortolking af indhold + + + unexpected character + uventet tegn + + + invalid name for processing instruction + + + + version expected while reading the XML declaration + version forventet under læsning af XML-deklaration + + + wrong value for standalone declaration + + + + encoding declaration or standalone declaration expected while reading the XML declaration + + + + standalone declaration expected while reading the XML declaration + + + + error occurred while parsing document type definition + der opstod fejl under fortolking af dokumenttypedefinition + + + letter is expected + + + + error occurred while parsing comment + der opstod fejl under fortolking af kommentar + + + error occurred while parsing reference + der opstod fejl under fortolking af reference + + + internal general entity reference not allowed in DTD + + + + external parsed general entity reference not allowed in attribute value + + + + external parsed general entity reference not allowed in DTD + + + + unparsed entity reference in wrong context + ufortolket enhedsreference i forkert kontekst + + + recursive entities + + + + error in the text declaration of an external entity + fejl i tekstdeklaration pĂ¥ en ekstern enhed + + + + QXmlStream + + + Extra content at end of document. + Ekstra indhold sidst i dokumentet. + + + Invalid entity value. + Ugyldig enhedsværdi. + + + Invalid XML character. + Ugyldigt XML-tegn. + + + Sequence ']]>' not allowed in content. + Sekvens ']]>' ikke tilladt i indhold. + + + Namespace prefix '%1' not declared + Navnerumspræfiks '%1' ikke deklareret + + + Attribute redefined. + + + + Unexpected character '%1' in public id literal. + + + + Invalid XML version string. + Ugyldigt XML-versionsstreng. + + + Unsupported XML version. + XML-version understøttes ikke. + + + %1 is an invalid encoding name. + + + + Encoding %1 is unsupported + + + + Standalone accepts only yes or no. + + + + Invalid attribute in XML declaration. + + + + Premature end of document. + + + + Invalid document. + Ugyldigt dokument. + + + Expected + Forventet + + + , but got ' + , men fik ' + + + Unexpected ' + Uventet ' + + + Expected character data. + Forventet tegndata. + + + Recursive entity detected. + + + + Start tag expected. + Start-tag forventet. + + + XML declaration not at start of document. + XML-deklaration ikke i starten af dokumentet. + + + NDATA in parameter entity declaration. + + + + %1 is an invalid processing instruction name. + + + + Invalid processing instruction name. + + + + Illegal namespace declaration. + Ulovligt navnerumsdeklaration. + + + + Invalid XML name. + Ugyldigt XML-navn. + + + Opening and ending tag mismatch. + Ă…bner og afslutter tag-mismatch. + + + Reference to unparsed entity '%1'. + Reference to ufortolket enhed '%1'. + + + Entity '%1' not declared. + Enheden '%1' ikke deklareret. + + + Reference to external entity '%1' in attribute value. + Reference til ekstern enhed '%1' i attributværdi. + + + Invalid character reference. + Ugyldig tegnreference. + + + Encountered incorrectly encoded content. + + + + The standalone pseudo attribute must appear after the encoding. + + + + + %1 is an invalid PUBLIC identifier. + + + + + QtXmlPatterns + + + An %1-attribute with value %2 has already been declared. + + + + An %1-attribute must have a valid %2 as value, which %3 isn't. + + + + + Network timeout. + + + + + Element %1 can't be serialized because it appears outside the document element. + + + + + Year %1 is invalid because it begins with %2. + + + + Day %1 is outside the range %2..%3. + + + + Month %1 is outside the range %2..%3. + + + + Overflow: Can't represent date %1. + + + + Day %1 is invalid for month %2. + + + + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; + + + + Time %1:%2:%3.%4 is invalid. + + + + Overflow: Date can't be represented. + + + + At least one component must be present. + + + + At least one time component must appear after the %1-delimiter. + + + + + No operand in an integer division, %1, can be %2. + + + + The first operand in an integer division, %1, cannot be infinity (%2). + + + + The second operand in a division, %1, cannot be zero (%2). + + + + + %1 is not a valid value of type %2. + + + + + When casting to %1 from %2, the source value cannot be %3. + + + + + Integer division (%1) by zero (%2) is undefined. + + + + Division (%1) by zero (%2) is undefined. + + + + Modulus division (%1) by zero (%2) is undefined. + + + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. + + + + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + + + + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. + + + + + A value of type %1 cannot have an Effective Boolean Value. + + + + + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. + + + + + Value %1 of type %2 exceeds maximum (%3). + + + + Value %1 of type %2 is below minimum (%3). + + + + + A value of type %1 must contain an even number of digits. The value %2 does not. + + + + %1 is not valid as a value of type %2. + + + + + Operator %1 cannot be used on type %2. + + + + Operator %1 cannot be used on atomic values of type %2 and %3. + + + + + The namespace URI in the name for a computed attribute cannot be %1. + + + + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. + + + + + Type error in cast, expected %1, received %2. + + + + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. + + + + + No casting is possible with %1 as the target type. + + + + It is not possible to cast from %1 to %2. + + + + Casting to %1 is not possible because it is an abstract type, and can therefore never be instantiated. + + + + It's not possible to cast the value %1 of type %2 to %3 + + + + Failure when casting from %1 to %2: %3 + + + + + A comment cannot contain %1 + + + + A comment cannot end with a %1. + + + + + No comparisons can be done involving the type %1. + + + + Operator %1 is not available between atomic values of type %2 and %3. + + + + + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. + + + + + A library module cannot be evaluated directly. It must be imported from a main module. + + + + No template by name %1 exists. + + + + + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + + + + A positional predicate must evaluate to a single numeric value. + + + + + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, is %2 invalid. + + + + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. + + + + + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. + + + + + The data of a processing instruction cannot contain the string %1 + + + + + No namespace binding exists for the prefix %1 + + + + + No namespace binding exists for the prefix %1 in %2 + + + + + %1 is an invalid %2 + + + + + %1 takes at most %n argument(s). %2 is therefore invalid. + + + + + + + %1 requires at least %n argument(s). %2 is therefore invalid. + + + + + + + + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + + + + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + + + + + %1 is not a valid XML 1.0 character. + + + + + The first argument to %1 cannot be of type %2. + + + + + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. + + + + + %1 was called. + + + + + %1 must be followed by %2 or %3, not at the end of the replacement string. + + + + In the replacement string, %1 must be followed by at least one digit when not escaped. + + + + In the replacement string, %1 can only be used to escape itself or %2, not %3 + + + + + %1 matches newline characters + + + + %1 and %2 match the start and end of a line. + + + + Matches are case insensitive + + + + Whitespace characters are removed, except when they appear in character classes + + + + %1 is an invalid regular expression pattern: %2 + + + + %1 is an invalid flag for regular expressions. Valid flags are: + + + + + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. + + + + + It will not be possible to retrieve %1. + + + + + The root node of the second argument to function %1 must be a document node. %2 is not a document node. + + + + + The default collection is undefined + + + + %1 cannot be retrieved + + + + + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). + + + + + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + + + + %1 is not a whole number of minutes. + + + + + Required cardinality is %1; got cardinality %2. + + + + + The item %1 did not match the required type %2. + + + + %1 is an unknown schema type. + + + + Only one %1 declaration can occur in the query prolog. + + + + The initialization of variable %1 depends on itself + + + + No variable by name %1 exists + + + + + The variable %1 is unused + + + + + Version %1 is not supported. The supported XQuery version is 1.0. + + + + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + + + + No function with signature %1 is available + + + + A default namespace declaration must occur before function, variable, and option declarations. + + + + Namespace declarations must occur before function, variable, and option declarations. + + + + Module imports must occur before function, variable, and option declarations. + + + + It is not possible to redeclare prefix %1. + + + + Prefix %1 is already declared in the prolog. + + + + The name of an option must have a prefix. There is no default namespace for options. + + + + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + + + + The target namespace of a %1 cannot be empty. + + + + The module import feature is not supported + + + + No value is available for the external variable by name %1. + + + + A construct was encountered which only is allowed in XQuery. + + + + A template by name %1 has already been declared. + + + + The keyword %1 cannot occur with any other mode name. + + + + The value of attribute %1 must of type %2, which %3 isn't. + + + + The prefix %1 can not be bound. By default, it is already bound to the namespace %2. + + + + A variable by name %1 has already been declared. + + + + A stylesheet function must have a prefixed name. + + + + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + + + + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + + + + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + + + + A function already exists with the signature %1. + + + + No external functions are supported. All supported functions can be used directly, without first declaring them as external + + + + An argument by name %1 has already been declared. Every argument name must be unique. + + + + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + + + + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + + + + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + + + + In an XSL-T pattern, function %1 cannot have a third argument. + + + + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + + + + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + + + + %1 is an invalid template mode name. + + + + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + + + + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + + + + None of the pragma expressions are supported. Therefore, a fallback expression must be present + + + + Each name of a template parameter must be unique; %1 is duplicated. + + + + The %1-axis is unsupported in XQuery + + + + %1 is not a valid name for a processing-instruction. + + + + %1 is not a valid numeric literal. + + + + No function by name %1 is available. + + + + The namespace URI cannot be the empty string when binding to a prefix, %1. + + + + %1 is an invalid namespace URI. + + + + It is not possible to bind to the prefix %1 + + + + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + + + + Two namespace declaration attributes have the same name: %1. + + + + The namespace URI must be a constant and cannot use enclosed expressions. + + + + An attribute by name %1 has already appeared on this element. + + + + A direct element constructor is not well-formed. %1 is ended with %2. + + + + The name %1 does not refer to any schema type. + + + + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + + + + %1 is not an atomic type. Casting is only possible to atomic types. + + + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + + + + The name of an extension expression must be in a namespace. + + + + + empty + + + + zero or one + + + + exactly one + + + + one or more + + + + zero or more + + + + + Required type is %1, but %2 was found. + + + + Promoting %1 to %2 may cause loss of precision. + + + + The focus is undefined. + + + + + It's not possible to add attributes after any other kind of node. + + + + An attribute by name %1 has already been created. + + + + + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. + + + + + Attribute %1 can't be serialized because it appears at the top level. + + + + + %1 is an unsupported encoding. + + + + %1 contains octets which are disallowed in the requested encoding %2. + + + + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. + + + + + Ambiguous rule match. + + + + + In a namespace constructor, the value for a namespace value cannot be an empty string. + + + + The prefix must be a valid %1, which %2 is not. + + + + The prefix %1 cannot be bound. + + + + Only the prefix %1 can be bound to %2 and vice versa. + + + + + Circularity detected + + + + + The parameter %1 is required, but no corresponding %2 is supplied. + + + + The parameter %1 is passed, but no corresponding %2 exists. + + + + + The URI cannot have a fragment + + + + + Element %1 is not allowed at this location. + + + + Text nodes are not allowed at this location. + + + + Parse error: %1 + + + + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + + + + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + + + + Unknown XSL-T attribute %1. + + + + Attribute %1 and %2 are mutually exclusive. + + + + In a simplified stylesheet module, attribute %1 must be present. + + + + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + + + + Element %1 must have at least one of the attributes %2 or %3. + + + + At least one mode must be specified in the %1-attribute on element %2. + + + + + Attribute %1 cannot appear on the element %2. Only the standard attributes can appear. + + + + Attribute %1 cannot appear on the element %2. Only %3 is allowed, and the standard attributes. + + + + Attribute %1 cannot appear on the element %2. Allowed is %3, %4, and the standard attributes. + + + + Attribute %1 cannot appear on the element %2. Allowed is %3, and the standard attributes. + + + + XSL-T attributes on XSL-T elements must be in the null namespace, not in the XSL-T namespace which %1 is. + + + + The attribute %1 must appear on element %2. + + + + The element with local name %1 does not exist in XSL-T. + + + + + Element %1 must come last. + + + + At least one %1-element must occur before %2. + + + + Only one %1-element can appear. + + + + At least one %1-element must occur inside %2. + + + + When attribute %1 is present on %2, a sequence constructor cannot be used. + + + + Element %1 must have either a %2-attribute or a sequence constructor. + + + + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + + + + Element %1 cannot have children. + + + + Element %1 cannot have a sequence constructor. + + + + The attribute %1 cannot appear on %2, when it is a child of %3. + + + + A parameter in a function cannot be declared to be a tunnel. + + + + This processor is not Schema-aware and therefore %1 cannot be used. + + + + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + + + + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + + + + Attribute %1 cannot have the value %2. + + + + The attribute %1 can only appear on the first %2 element. + + + + At least one %1 element must appear as child of %2. + + + + + VolumeSlider + + + Muted + + + + Volume: %1% + Lydstyrke: %1% + + + diff --git a/translations/qt_help_da.ts b/translations/qt_help_da.ts new file mode 100644 index 0000000..0e4a362 --- /dev/null +++ b/translations/qt_help_da.ts @@ -0,0 +1,354 @@ + + + + + QCLuceneResultWidget + + + Search Results + Søgeresultater + + + + Note: + Bemærk: + + + + The search results may not be complete since the documentation is still being indexed! + Søgeresultaterne kan være ufuldstændige, fordi dokumentationen stadig indekseres! + + + + Your search did not match any documents. + Søgningen matchede ikke nogen dokumenter. + + + + (The reason for this might be that the documentation is still being indexed.) + (Ă…rsagen kan være, at dokumentationen stadig indekseres.) + + + + QHelpCollectionHandler + + + The collection file is not set up yet! + Hjælpesamlingen er ikke konfigureret endnu! + + + + Cannot open collection file: %1 + Kan ikke Ă¥bne hjælpesamlingen: %1 + + + + Cannot create tables in file %1! + Kan ikke oprette tabler i filen %1! + + + + The specified collection file already exists! + Den angivne hjælpesamling findes allerede! + + + + Cannot create directory: %1 + Kan ikke oprette kataloget: %1 + + + + Cannot copy collection file: %1 + Kan ikke kopiere hjælpesamling: %1 + + + + Unknown filter! + Ukendt filter! + + + + Cannot register filter %1! + Kan ikke registrere filteret %1! + + + + Cannot open documentation file %1! + Kan ikke Ă¥bne dokumentationsfilen %1! + + + + Invalid documentation file! + Ugyldig dokumentationsfil! + + + + The namespace %1 was not registered! + Navnerummet %1 blev ikke registreret! + + + + Namespace %1 already exists! + Navnerummet %1 findes allerede! + + + + Cannot register namespace! + Kan ikke registrere navnerummet! + + + + Cannot open database to optimize! + Kan ikke Ă¥bne den database, der skal optimeres! + + + + QHelpDBReader + + + Cannot open DB! + Kan ikke Ă¥bne DB! + + + + QHelpEngineCore + + + The specified namespace does not exist! + Det angivne navnerum findes ikke! + + + + QHelpEngineCorePrivate + + + Cannot open collection file %1! + Kan ikke Ă¥bne hjælpesamlingen %1! + + + + Cannot open documentation file %1! + Kan ikke Ă¥bne dokumentationsfilen %1! + + + + QHelpGenerator + + + Invalid help data! + Ugyldigt hjælpedata! + + + + No output file name specified! + Der er ikke anført et output-filnavn! + + + + The file %1 already exists! + Filen %1 findes allerede! + + + + Building up file structure... + Bygger filstruktur... + + + + Cannot open DB! + Kan ikke Ă¥bne DB! + + + + Cannot register namespace %1! + Kan ikke registrere navnerummet %1! + + + + Insert custom filters... + Indsæt brugerdefinerede filtre... + + + + Insert help data for filter section (%1 of %2)... + Indsæt hjælpedata til filtersektion (%1 af %2)... + + + + Documentation successfully generated. + Dokumentationen blev genereret. + + + + Some tables already exist! + Nogle af tabellerne findes allerede! + + + + Cannot create tables! + Kan ikke oprette tabeller! + + + + Cannot register virtual folder! + Kan ikke registrere virtuel mappe! + + + + Insert files... + Indsæt filer... + + + + The file %1 does not exist! Skipping it. + Filen %1 findes ikke, og den springes over. + + + + Cannot open file %1! Skipping it. + Kan ikke Ă¥bne filen %1, og den springes over. + + + + Cannot insert file data into database! + Kan ikke indsætte fildata i databasen! + + + + The filter %1 is already registered! + Filtret %1 er allerede registreret! + + + + Cannot register filter %1! + Kan ikke registrere filtret %1! + + + + Insert indices... + Indsæt indeks... + + + + Insert contents... + Indsæt indhold... + + + + Cannot insert contents! + Kan ikke indsætte indhold! + + + + Cannot register contents! + Kan ikke registrere indhold! + + + + QHelpSearchQueryWidget + + + Search for: + Søg efter: + + + + Search + Søg + + + + Advanced search + Avanceret søgning + + + + words <B>similar</B> to: + ord <B>tilsvarende</B>: + + + + <B>without</B> the words: + <B>uden</B> ordene: + + + + with <B>exact phrase</B>: + med den <B>eksakte sætning</B>: + + + + with <B>all</B> of the words: + med <B>alle</B> ordene: + + + + with <B>at least one</B> of the words: + med <B>mindst Ă©t</B> af ordene: + + + + QHelpSearchResultWidget + + + 0 - 0 of 0 Hits + 0 - 0 af 0 Hits + + + + QHelpSearchResultWidgetPrivate + + + %1 - %2 of %3 Hits + %1 - %2 af %3 Hits + + + + QObject + + + Untitled + Ingen titel + + + + Unknown token at line %1. + Ukendt symbol pĂ¥ linie %1. + + + + Unknown token at line %1. Expected "QtHelpProject"! + Ukendt symbol pĂ¥ linie %1. Forventet "QtHelpProject"! + + + + A virtual folder must not contain a '/' character! + En virtuel mappe mĂ¥ ikke indholde tegnet '/'! + + + + A namespace must not contain a '/' character! + Et navnerum mĂ¥ ikke indeholde tegnet '/'! + + + + Missing namespace in QtHelpProject. + Navnerum i +++ mangler. + + + + Missing virtual folder in QtHelpProject + Virtuel mappe i QtHelpProject mangler + + + + Missing attribute in keyword at line %1. + Attribut i nøgleord pĂ¥ linie %1 mangler. + + + + The input file %1 could not be opened! + Input-filen %1 kunne ikke Ă¥bnes! + + + -- cgit v0.12 From d94ed47b7748826fc2b9fba774cce51a54c24880 Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 21 May 2009 11:44:19 +1000 Subject: Fixes conditional jump on uninitialised value As found by valgrind. Also add error reporting that was missing. Reviewed-by: Justin McPherson --- src/sql/drivers/oci/qsql_oci.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index d63c482..a7031b1 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -1789,7 +1789,7 @@ bool QOCIResult::prepare(const QString& query) bool QOCIResult::exec() { int r = 0; - ub2 stmtType; + ub2 stmtType=0; ub4 iters; ub4 mode; QList tmpStorage; @@ -1803,6 +1803,16 @@ bool QOCIResult::exec() OCI_ATTR_STMT_TYPE, d->err); + if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) { + qOraWarning("QOCIResult::exec: Unable to get statement type:", d->err); + setLastError(qMakeError(QCoreApplication::translate("QOCIResult", + "Unable to get statement type"), QSqlError::StatementError, d->err)); +#ifdef QOCI_DEBUG + qDebug() << "lastQuery()" << lastQuery(); +#endif + return false; + } + if (stmtType == OCI_STMT_SELECT) { iters = 0; mode = OCI_DEFAULT; -- cgit v0.12 From 2cb36aed053147ecc91f72ed76074962a66b76f0 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Thu, 21 May 2009 14:08:02 +1000 Subject: Fix build regression caused by ba5fb9f05c891feac8ab69006189de1aaafebc18. The previous "fix" caused the effect of the line before the change to be discarded, which breaks the mac binary package builds. When reviewing changes, please read the lines of context given in the patch - they are included for a reason. Acked-by: Lincoln Ramsay Acked-by: Rohan McGovern --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 20bf457..c882b29 100755 --- a/configure +++ b/configure @@ -2717,7 +2717,7 @@ if [ "$PLATFORM_MAC" = "yes" ]; then # Build commmand line arguments we can pass to the compiler during configure tests # by prefixing each arch with "-arch". CFG_MAC_ARCHS_GCC_FORMAT="${CFG_MAC_ARCHS/x86/i386}" - CFG_MAC_ARCHS_GCC_FORMAT="${CFG_MAC_ARCHS/i386_64/x86_64}" + CFG_MAC_ARCHS_GCC_FORMAT="${CFG_MAC_ARCHS_GCC_FORMAT/i386_64/x86_64}" for ARCH in $CFG_MAC_ARCHS_GCC_FORMAT; do MAC_ARCHS_COMMANDLINE="$MAC_ARCHS_COMMANDLINE -arch $ARCH" done -- cgit v0.12 From 7383e03bfd473f6e79718f3da7d504977a677541 Mon Sep 17 00:00:00 2001 From: Bill King Date: Thu, 21 May 2009 14:27:27 +1000 Subject: Fixes one of the fields of mysql bound params not initialised. Found by valgrind, value isn't set but is used, fixes this. Reviewed-by: Justin McPherson --- src/sql/drivers/mysql/qsql_mysql.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 51fc306..53645c9 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -927,6 +927,7 @@ bool QMYSQLResult::exec() nullVector[i] = static_cast(val.isNull()); currBind->is_null = &nullVector[i]; currBind->length = 0; + currBind->is_unsigned = 0; switch (val.type()) { case QVariant::ByteArray: @@ -973,7 +974,6 @@ bool QMYSQLResult::exec() currBind->buffer_type = MYSQL_TYPE_DOUBLE; currBind->buffer = data; currBind->buffer_length = sizeof(double); - currBind->is_unsigned = 0; break; case QVariant::LongLong: case QVariant::ULongLong: @@ -989,7 +989,6 @@ bool QMYSQLResult::exec() currBind->buffer_type = MYSQL_TYPE_STRING; currBind->buffer = const_cast(ba.constData()); currBind->buffer_length = ba.length(); - currBind->is_unsigned = 0; break; } } } -- cgit v0.12 From b0078f00058f8d2a9fbe4742f52386a866b2bd97 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Thu, 21 May 2009 17:04:38 +1000 Subject: Fix missing/outdated license headers. Reviewed-by: Trust Me --- examples/animation/sub-attaq/boat_p.h | 13 +++- examples/animation/sub-attaq/submarine_p.h | 13 +++- examples/statemachine/tankgame/gameitem.cpp | 41 +++++++++++ examples/statemachine/tankgame/gameitem.h | 41 +++++++++++ .../statemachine/tankgame/gameovertransition.cpp | 45 +++++++++++- .../statemachine/tankgame/gameovertransition.h | 41 +++++++++++ examples/statemachine/tankgame/main.cpp | 41 +++++++++++ examples/statemachine/tankgame/mainwindow.cpp | 81 ++++++++++++++++------ examples/statemachine/tankgame/mainwindow.h | 45 +++++++++++- examples/statemachine/tankgame/plugin.h | 41 +++++++++++ examples/statemachine/tankgame/rocketitem.cpp | 43 +++++++++++- examples/statemachine/tankgame/rocketitem.h | 44 +++++++++++- examples/statemachine/tankgame/tankitem.cpp | 73 ++++++++++++++----- examples/statemachine/tankgame/tankitem.h | 47 ++++++++++++- .../tankgameplugins/random_ai/random_ai_plugin.cpp | 41 +++++++++++ .../tankgameplugins/random_ai/random_ai_plugin.h | 43 +++++++++++- .../tankgameplugins/seek_ai/seek_ai.cpp | 57 ++++++++++++--- .../statemachine/tankgameplugins/seek_ai/seek_ai.h | 61 +++++++++++++--- .../tankgameplugins/spin_ai/spin_ai.cpp | 51 ++++++++++++-- .../statemachine/tankgameplugins/spin_ai/spin_ai.h | 45 +++++++++++- .../spin_ai_with_error/spin_ai_with_error.cpp | 49 +++++++++++-- .../spin_ai_with_error/spin_ai_with_error.h | 45 +++++++++++- src/gui/statemachine/qbasickeyeventtransition.cpp | 34 ++++++++- src/gui/statemachine/qbasickeyeventtransition_p.h | 34 ++++++++- .../statemachine/qbasicmouseeventtransition.cpp | 34 ++++++++- .../statemachine/qbasicmouseeventtransition_p.h | 34 ++++++++- src/gui/statemachine/qguistatemachine.cpp | 36 +++++++++- src/gui/statemachine/qkeyeventtransition.cpp | 34 ++++++++- src/gui/statemachine/qkeyeventtransition.h | 34 ++++++++- src/gui/statemachine/qmouseeventtransition.cpp | 34 ++++++++- src/gui/statemachine/qmouseeventtransition.h | 34 ++++++++- 31 files changed, 1209 insertions(+), 100 deletions(-) diff --git a/examples/animation/sub-attaq/boat_p.h b/examples/animation/sub-attaq/boat_p.h index c934bc5..a8a24a6 100644 --- a/examples/animation/sub-attaq/boat_p.h +++ b/examples/animation/sub-attaq/boat_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -42,6 +42,17 @@ #ifndef BOAT_P_H #define BOAT_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + //Own #include "bomb.h" #include "graphicsscene.h" diff --git a/examples/animation/sub-attaq/submarine_p.h b/examples/animation/sub-attaq/submarine_p.h index 561af4a..8c31eb7 100644 --- a/examples/animation/sub-attaq/submarine_p.h +++ b/examples/animation/sub-attaq/submarine_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -42,6 +42,17 @@ #ifndef SUBMARINE_P_H #define SUBMARINE_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + //Own #include "animationmanager.h" #include "submarine.h" diff --git a/examples/statemachine/tankgame/gameitem.cpp b/examples/statemachine/tankgame/gameitem.cpp index 1a2af71..ad8b37c 100644 --- a/examples/statemachine/tankgame/gameitem.cpp +++ b/examples/statemachine/tankgame/gameitem.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "gameitem.h" #include diff --git a/examples/statemachine/tankgame/gameitem.h b/examples/statemachine/tankgame/gameitem.h index 33caf71..90b0a6c 100644 --- a/examples/statemachine/tankgame/gameitem.h +++ b/examples/statemachine/tankgame/gameitem.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef GAMEITEM_H #define GAMEITEM_H diff --git a/examples/statemachine/tankgame/gameovertransition.cpp b/examples/statemachine/tankgame/gameovertransition.cpp index cec786e..360e902 100644 --- a/examples/statemachine/tankgame/gameovertransition.cpp +++ b/examples/statemachine/tankgame/gameovertransition.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "gameovertransition.h" #include "tankitem.h" @@ -8,7 +49,7 @@ GameOverTransition::GameOverTransition(QAbstractState *targetState) : QSignalTransition(new QSignalMapper(), SIGNAL(mapped(QObject*))) { setTargetState(targetState); - + QSignalMapper *mapper = qobject_cast(senderObject()); mapper->setParent(this); } @@ -36,4 +77,4 @@ bool GameOverTransition::eventTest(QEvent *e) } else { return false; } -} \ No newline at end of file +} diff --git a/examples/statemachine/tankgame/gameovertransition.h b/examples/statemachine/tankgame/gameovertransition.h index 9a86b83..5e99a75 100644 --- a/examples/statemachine/tankgame/gameovertransition.h +++ b/examples/statemachine/tankgame/gameovertransition.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef GAMEOVERTRANSITION_H #define GAMEOVERTRANSITION_H diff --git a/examples/statemachine/tankgame/main.cpp b/examples/statemachine/tankgame/main.cpp index 26fc1bb..185ad68 100644 --- a/examples/statemachine/tankgame/main.cpp +++ b/examples/statemachine/tankgame/main.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include #include "mainwindow.h" diff --git a/examples/statemachine/tankgame/mainwindow.cpp b/examples/statemachine/tankgame/mainwindow.cpp index 3437140..46e0db3 100644 --- a/examples/statemachine/tankgame/mainwindow.cpp +++ b/examples/statemachine/tankgame/mainwindow.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "mainwindow.h" #include "tankitem.h" #include "rocketitem.h" @@ -97,7 +138,7 @@ void MainWindow::init() addWall(QRectF(centerOfMap - QPointF(-50.0, -60.0), centerOfMap - QPointF(50.0, -50.0))); addWall(QRectF(centerOfMap + QPointF(-50.0, -50.0), centerOfMap + QPointF(-40.0, 50.0))); addWall(QRectF(centerOfMap - QPointF(-50.0, -50.0), centerOfMap - QPointF(-40.0, 50.0))); - + addWall(QRectF(sceneRect.topLeft() + QPointF(sceneRect.width() / 2.0 - 5.0, -10.0), sceneRect.topLeft() + QPointF(sceneRect.width() / 2.0 + 5.0, 100.0))); addWall(QRectF(sceneRect.bottomLeft() + QPointF(sceneRect.width() / 2.0 - 5.0, 10.0), @@ -108,18 +149,18 @@ void MainWindow::init() sceneRect.topRight() + QPointF(-100.0, sceneRect.height() / 2.0 + 5.0))); - QAction *addTankAction = menuBar()->addAction("&Add tank"); - QAction *runGameAction = menuBar()->addAction("&Run game"); + QAction *addTankAction = menuBar()->addAction("&Add tank"); + QAction *runGameAction = menuBar()->addAction("&Run game"); runGameAction->setObjectName("runGameAction"); - QAction *stopGameAction = menuBar()->addAction("&Stop game"); + QAction *stopGameAction = menuBar()->addAction("&Stop game"); menuBar()->addSeparator(); QAction *quitAction = menuBar()->addAction("&Quit"); - + connect(addTankAction, SIGNAL(triggered()), this, SLOT(addTank())); connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - - m_machine = new QStateMachine(this); - QState *stoppedState = new QState(m_machine->rootState()); + + m_machine = new QStateMachine(this); + QState *stoppedState = new QState(m_machine->rootState()); stoppedState->setObjectName("stoppedState"); stoppedState->assignProperty(runGameAction, "enabled", true); stoppedState->assignProperty(stopGameAction, "enabled", false); @@ -127,19 +168,19 @@ void MainWindow::init() m_machine->setInitialState(stoppedState); //! [5] - QState *spawnsAvailable = new QState(stoppedState); + QState *spawnsAvailable = new QState(stoppedState); spawnsAvailable->assignProperty(addTankAction, "enabled", true); - QState *noSpawnsAvailable = new QState(stoppedState); + QState *noSpawnsAvailable = new QState(stoppedState); noSpawnsAvailable->assignProperty(addTankAction, "enabled", false); -//! [5] +//! [5] spawnsAvailable->setObjectName("spawnsAvailable"); noSpawnsAvailable->setObjectName("noSpawnsAvailable"); spawnsAvailable->addTransition(this, SIGNAL(mapFull()), noSpawnsAvailable); //! [3] - QHistoryState *hs = new QHistoryState(stoppedState); + QHistoryState *hs = new QHistoryState(stoppedState); hs->setDefaultState(spawnsAvailable); //! [3] hs->setObjectName("hs"); @@ -158,7 +199,7 @@ void MainWindow::init() gameOverState->setObjectName("gameOverState"); gameOverState->assignProperty(stopGameAction, "enabled", false); connect(gameOverState, SIGNAL(entered()), this, SLOT(gameOver())); - + stoppedState->addTransition(runGameAction, SIGNAL(triggered()), m_runningState); m_runningState->addTransition(stopGameAction, SIGNAL(triggered()), stoppedState); @@ -168,12 +209,12 @@ void MainWindow::init() QTimer *timer = new QTimer(this); timer->setInterval(100); connect(timer, SIGNAL(timeout()), this, SLOT(runStep())); - connect(m_runningState, SIGNAL(entered()), timer, SLOT(start())); + connect(m_runningState, SIGNAL(entered()), timer, SLOT(start())); connect(m_runningState, SIGNAL(exited()), timer, SLOT(stop())); m_machine->start(); m_time.start(); -} +} void MainWindow::runStep() { @@ -206,7 +247,7 @@ void MainWindow::gameOver() } } - QMessageBox::information(this, "Game over!", + QMessageBox::information(this, "Game over!", QString::fromLatin1("The tank played by '%1' has won!").arg(lastTankStanding->objectName())); } @@ -216,7 +257,7 @@ void MainWindow::addRocket() if (tankItem != 0) { RocketItem *rocketItem = new RocketItem; - QPointF s = tankItem->mapToScene(QPointF(tankItem->boundingRect().right() + 10.0, + QPointF s = tankItem->mapToScene(QPointF(tankItem->boundingRect().right() + 10.0, tankItem->boundingRect().center().y())); rocketItem->setPos(s); rocketItem->setDirection(tankItem->direction()); @@ -264,10 +305,10 @@ void MainWindow::addTank() bool ok; //! [1] - QString selectedName = QInputDialog::getItem(this, "Select a tank type", "Tank types", + QString selectedName = QInputDialog::getItem(this, "Select a tank type", "Tank types", itemNames, 0, false, &ok); //! [1] - + if (ok && !selectedName.isEmpty()) { int idx = itemNames.indexOf(selectedName); if (Plugin *plugin = idx >= 0 ? items.at(idx) : 0) { @@ -280,7 +321,7 @@ void MainWindow::addTank() emit mapFull(); m_gameOverTransition->addTankItem(tankItem); - + QState *region = new QState(m_runningState); region->setObjectName(QString::fromLatin1("region%1").arg(m_spawns.size())); //! [2] diff --git a/examples/statemachine/tankgame/mainwindow.h b/examples/statemachine/tankgame/mainwindow.h index 391ab77..4ae8f7a 100644 --- a/examples/statemachine/tankgame/mainwindow.h +++ b/examples/statemachine/tankgame/mainwindow.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef MAINWINDOW_H #define MAINWINDOW_H @@ -37,14 +78,14 @@ private: void addWall(const QRectF &wall); QGraphicsScene *m_scene; - + QStateMachine *m_machine; QState *m_runningState; GameOverTransition *m_gameOverTransition; QList m_spawns; QTime m_time; - + bool m_started : 1; }; diff --git a/examples/statemachine/tankgame/plugin.h b/examples/statemachine/tankgame/plugin.h index 006ad78..ddd10b7 100644 --- a/examples/statemachine/tankgame/plugin.h +++ b/examples/statemachine/tankgame/plugin.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef PLUGIN_H #define PLUGIN_H diff --git a/examples/statemachine/tankgame/rocketitem.cpp b/examples/statemachine/tankgame/rocketitem.cpp index c324980..3ace8e8 100644 --- a/examples/statemachine/tankgame/rocketitem.cpp +++ b/examples/statemachine/tankgame/rocketitem.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "rocketitem.h" #include "tankitem.h" @@ -53,7 +94,7 @@ void RocketItem::idle(qreal elapsed) if (tankItem != 0) tankItem->hitByRocket(); } - + scene()->removeItem(this); delete this; } diff --git a/examples/statemachine/tankgame/rocketitem.h b/examples/statemachine/tankgame/rocketitem.h index 189a1dd..31146a6 100644 --- a/examples/statemachine/tankgame/rocketitem.h +++ b/examples/statemachine/tankgame/rocketitem.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef ROCKETITEM_H #define ROCKETITEM_H @@ -12,7 +53,7 @@ public: virtual void idle(qreal elapsed); qreal speed() const { return 100.0; } void setDirection(qreal direction) { m_direction = direction; } - + protected: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QRectF boundingRect() const; @@ -22,5 +63,4 @@ private: qreal m_distance; }; - #endif diff --git a/examples/statemachine/tankgame/tankitem.cpp b/examples/statemachine/tankgame/tankitem.cpp index c322d21..393d65f 100644 --- a/examples/statemachine/tankgame/tankitem.cpp +++ b/examples/statemachine/tankgame/tankitem.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "tankitem.h" #include @@ -35,15 +76,15 @@ public: m_reverse = m_distance < 0.0; } - bool apply(qreal timeDelta) + bool apply(qreal timeDelta) { qreal dist = timeDelta * item()->speed() * (m_reverse ? -1.0 : 1.0); - bool done = false; - if (qAbs(m_distance) < qAbs(dist)) { + bool done = false; + if (qAbs(m_distance) < qAbs(dist)) { done = true; dist = m_distance; - } + } m_distance -= dist; qreal a = item()->direction() * M_PI / 180.0; @@ -69,14 +110,14 @@ public: m_reverse = m_distance < 0.0; } - bool apply(qreal timeDelta) + bool apply(qreal timeDelta) { qreal dist = timeDelta * item()->angularSpeed() * (m_reverse ? -1.0 : 1.0); - bool done = false; + bool done = false; if (qAbs(m_distance) < qAbs(dist)) { done = true; dist = m_distance; - } + } m_distance -= dist; item()->setDirection(item()->direction() + dist); @@ -88,7 +129,7 @@ private: bool m_reverse; }; -TankItem::TankItem(QObject *parent) +TankItem::TankItem(QObject *parent) : GameItem(parent), m_currentAction(0), m_currentDirection(0.0), m_enabled(true) { connect(this, SIGNAL(cannonFired()), this, SIGNAL(actionCompleted())); @@ -106,7 +147,7 @@ void TankItem::idle(qreal elapsed) QGraphicsItem *item = 0; qreal distance = distanceToObstacle(&item); if (TankItem *tankItem = qgraphicsitem_cast(item)) - emit tankSpotted(tankItem->direction(), distance); + emit tankSpotted(tankItem->direction(), distance); } } } @@ -119,7 +160,7 @@ void TankItem::hitByRocket() void TankItem::setAction(Action *newAction) { - if (m_currentAction != 0) + if (m_currentAction != 0) delete m_currentAction; m_currentAction = newAction; @@ -184,9 +225,9 @@ void TankItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidge QRectF cannonBase = brect.adjusted(10.0, 6.0, -12.0, -6.0); painter->drawEllipse(cannonBase); - painter->drawRect(QRectF(QPointF(cannonBase.center().x(), cannonBase.center().y() - 2.0), + painter->drawRect(QRectF(QPointF(cannonBase.center().x(), cannonBase.center().y() - 2.0), QPointF(brect.right(), cannonBase.center().y() + 2.0))); - + // left track painter->setBrush(QBrush(Qt::black, Qt::VerPattern)); QRectF leftTrackRect = QRectF(brect.topLeft(), QPointF(brect.right() - 2.0, brect.top() + 4.0)); @@ -223,7 +264,7 @@ qreal TankItem::direction() const void TankItem::setDirection(qreal newDirection) { - int fullRotations = int(newDirection) / 360; + int fullRotations = int(newDirection) / 360; newDirection -= fullRotations * 360.0; qreal diff = newDirection - m_currentDirection; @@ -245,8 +286,8 @@ qreal TankItem::distanceToObstacle(QGraphicsItem **obstacle) const QPointF nextPosition = tryMove(requestedPosition, 0, &collidedItem); if (collidedItem != 0) { if (obstacle != 0) - *obstacle = collidedItem; - + *obstacle = collidedItem; + QPointF d = nextPosition - pos(); return sqrt(pow(d.x(), 2) + pow(d.y(), 2)); } else { @@ -259,5 +300,3 @@ qreal TankItem::distanceToObstacle() const return distanceToObstacle(0); } - - diff --git a/examples/statemachine/tankgame/tankitem.h b/examples/statemachine/tankgame/tankitem.h index 9475397..942fca8 100644 --- a/examples/statemachine/tankgame/tankitem.h +++ b/examples/statemachine/tankgame/tankitem.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef TANKITEM_H #define TANKITEM_H @@ -12,9 +53,9 @@ class TankItem: public GameItem Q_PROPERTY(bool enabled READ enabled WRITE setEnabled) Q_PROPERTY(qreal direction READ direction WRITE turnTo) Q_PROPERTY(qreal distanceToObstacle READ distanceToObstacle) -public: +public: TankItem(QObject *parent = 0); - + void setColor(const QColor &color) { m_color = color; } QColor color() const { return m_color; } @@ -53,7 +94,7 @@ public slots: //! [0] protected: - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value); private: diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp index c196247..d360de9 100644 --- a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp +++ b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "random_ai_plugin.h" #include diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h index f5e3b6f..9faeeac 100644 --- a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h +++ b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef RANDOM_AI_PLUGIN_H #define RANDOM_AI_PLUGIN_H @@ -19,7 +60,7 @@ signals: void moveForwardsSelected(); void moveBackwardsSelected(); void turnSelected(); - + protected: void onEntry(QEvent *) { diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp index 2fb05d4..6aae015 100644 --- a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp +++ b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "seek_ai.h" QState *SeekAi::create(QState *parentState, QObject *tank) @@ -12,10 +53,10 @@ QState *SeekAi::create(QState *parentState, QObject *tank) QState *lookForNearestWall = new SearchState(tank, seek); lookForNearestWall->setObjectName("lookForNearestWall"); seek->setInitialState(lookForNearestWall); - + QState *driveToFirstObstacle = new QState(seek); driveToFirstObstacle->setObjectName("driveToFirstObstacle"); - lookForNearestWall->addTransition(lookForNearestWall, SIGNAL(nearestObstacleStraightAhead()), + lookForNearestWall->addTransition(lookForNearestWall, SIGNAL(nearestObstacleStraightAhead()), driveToFirstObstacle); QState *drive = new QState(driveToFirstObstacle); @@ -23,25 +64,25 @@ QState *SeekAi::create(QState *parentState, QObject *tank) driveToFirstObstacle->setInitialState(drive); connect(drive, SIGNAL(entered()), tank, SLOT(moveForwards())); connect(drive, SIGNAL(exited()), tank, SLOT(stop())); - + // Go in loop QState *finishedDriving = new QState(driveToFirstObstacle); finishedDriving->setObjectName("finishedDriving"); drive->addTransition(tank, SIGNAL(actionCompleted()), finishedDriving); finishedDriving->addTransition(drive); - + QState *turnTo = new QState(seek); turnTo->setObjectName("turnTo"); driveToFirstObstacle->addTransition(new CollisionTransition(tank, turnTo)); - + turnTo->addTransition(tank, SIGNAL(actionCompleted()), driveToFirstObstacle); ChaseState *chase = new ChaseState(tank, topLevel); - chase->setObjectName("chase"); - seek->addTransition(new TankSpottedTransition(tank, chase)); + chase->setObjectName("chase"); + seek->addTransition(new TankSpottedTransition(tank, chase)); chase->addTransition(chase, SIGNAL(finished()), driveToFirstObstacle); chase->addTransition(new TankSpottedTransition(tank, chase)); - + return topLevel; } diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h index 9d4aabc..e44ad07 100644 --- a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h +++ b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef SEEK_AI_H #define SEEK_AI_H @@ -15,18 +56,18 @@ class SearchState: public QState { Q_OBJECT public: - SearchState(QObject *tank, QState *parentState = 0) - : QState(parentState), - m_tank(tank), - m_distanceToTurn(360.0), + SearchState(QObject *tank, QState *parentState = 0) + : QState(parentState), + m_tank(tank), + m_distanceToTurn(360.0), m_nearestDistance(-1.0), - m_directionOfNearestObstacle(0.0) + m_directionOfNearestObstacle(0.0) { } public slots: void turnAlittle() - { + { qreal dist = m_tank->property("distanceToObstacle").toDouble(); if (m_nearestDistance < 0.0 || dist < m_nearestDistance) { @@ -72,7 +113,7 @@ private: class CollisionTransition: public QSignalTransition { public: - CollisionTransition(QObject *tank, QState *turnTo) + CollisionTransition(QObject *tank, QState *turnTo) : QSignalTransition(tank, SIGNAL(collision(QLineF))), m_tank(tank), m_turnTo(turnTo) @@ -99,7 +140,7 @@ protected: if (qrand() % 2 == 0) newDirection = angleOfWall; else - newDirection = angleOfWall - 180.0; + newDirection = angleOfWall - 180.0; m_turnTo->assignProperty(m_tank, "direction", newDirection); } @@ -115,7 +156,7 @@ class ChaseState: public QState class GoToLocationState: public QState { public: - GoToLocationState(QObject *tank, QState *parentState = 0) + GoToLocationState(QObject *tank, QState *parentState = 0) : QState(parentState), m_tank(tank), m_distance(0.0) { } @@ -123,7 +164,7 @@ class ChaseState: public QState void setDistance(qreal distance) { m_distance = distance; } protected: - void onEntry() + void onEntry() { QMetaObject::invokeMethod(m_tank, "moveForwards", Q_ARG(qreal, m_distance)); } diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp index de95f41..581a6b2 100644 --- a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp +++ b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "spin_ai.h" #include @@ -5,24 +46,24 @@ QState *SpinAi::create(QState *parentState, QObject *tank) { QState *topLevel = new QState(parentState); - QState *spinState = new SpinState(tank, topLevel); + QState *spinState = new SpinState(tank, topLevel); topLevel->setInitialState(spinState); // When tank is spotted, fire two times and go back to spin state QState *fireState = new QState(topLevel); QState *fireOnce = new QState(fireState); - fireState->setInitialState(fireOnce); + fireState->setInitialState(fireOnce); connect(fireOnce, SIGNAL(entered()), tank, SLOT(fireCannon())); QState *fireTwice = new QState(fireState); connect(fireTwice, SIGNAL(entered()), tank, SLOT(fireCannon())); - + fireOnce->addTransition(tank, SIGNAL(actionCompleted()), fireTwice); fireTwice->addTransition(tank, SIGNAL(actionCompleted()), spinState); - + spinState->addTransition(tank, SIGNAL(tankSpotted(qreal,qreal)), fireState); - + return topLevel; } diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h index d8d3d73..652e8b8 100644 --- a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h +++ b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef SPIN_AI_H #define SPIN_AI_H @@ -16,7 +57,7 @@ public: } public slots: - void spin() + void spin() { m_tank->setProperty("direction", m_tank->property("direction").toDouble() + 90.0); } @@ -25,7 +66,7 @@ protected: void onEntry(QEvent *) { connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); - spin(); + spin(); } void onExit(QEvent *) diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp index 5499ba3..19137b2 100644 --- a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp +++ b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "spin_ai_with_error.h" #include @@ -5,7 +46,7 @@ QState *SpinAiWithError::create(QState *parentState, QObject *tank) { QState *topLevel = new QState(parentState); - QState *spinState = new SpinState(tank, topLevel); + QState *spinState = new SpinState(tank, topLevel); topLevel->setInitialState(spinState); // When tank is spotted, fire two times and go back to spin state @@ -17,12 +58,12 @@ QState *SpinAiWithError::create(QState *parentState, QObject *tank) QState *fireTwice = new QState(fireState); connect(fireTwice, SIGNAL(entered()), tank, SLOT(fireCannon())); - + fireOnce->addTransition(tank, SIGNAL(actionCompleted()), fireTwice); fireTwice->addTransition(tank, SIGNAL(actionCompleted()), spinState); - + spinState->addTransition(tank, SIGNAL(tankSpotted(qreal,qreal)), fireState); - + return topLevel; } diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h index 456ba01..e040bf2 100644 --- a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h +++ b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef SPIN_AI_WITH_ERROR_H #define SPIN_AI_WITH_ERROR_H @@ -16,7 +57,7 @@ public: } public slots: - void spin() + void spin() { m_tank->setProperty("direction", m_tank->property("direction").toDouble() + 90.0); } @@ -25,7 +66,7 @@ protected: void onEntry(QEvent *) { connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); - spin(); + spin(); } void onExit(QEvent *) diff --git a/src/gui/statemachine/qbasickeyeventtransition.cpp b/src/gui/statemachine/qbasickeyeventtransition.cpp index fe89f81..f7f1eb6 100644 --- a/src/gui/statemachine/qbasickeyeventtransition.cpp +++ b/src/gui/statemachine/qbasickeyeventtransition.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/statemachine/qbasickeyeventtransition_p.h b/src/gui/statemachine/qbasickeyeventtransition_p.h index c4ff863..39fa6ad 100644 --- a/src/gui/statemachine/qbasickeyeventtransition_p.h +++ b/src/gui/statemachine/qbasickeyeventtransition_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/statemachine/qbasicmouseeventtransition.cpp b/src/gui/statemachine/qbasicmouseeventtransition.cpp index a18d1e8..20dd792 100644 --- a/src/gui/statemachine/qbasicmouseeventtransition.cpp +++ b/src/gui/statemachine/qbasicmouseeventtransition.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/statemachine/qbasicmouseeventtransition_p.h b/src/gui/statemachine/qbasicmouseeventtransition_p.h index 6a3ad1e..6c0afe4 100644 --- a/src/gui/statemachine/qbasicmouseeventtransition_p.h +++ b/src/gui/statemachine/qbasicmouseeventtransition_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp index b7563d7..612e43e 100644 --- a/src/gui/statemachine/qguistatemachine.cpp +++ b/src/gui/statemachine/qguistatemachine.cpp @@ -1,11 +1,41 @@ - /**************************************************************************** +/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/statemachine/qkeyeventtransition.cpp b/src/gui/statemachine/qkeyeventtransition.cpp index 0418501..f803711 100644 --- a/src/gui/statemachine/qkeyeventtransition.cpp +++ b/src/gui/statemachine/qkeyeventtransition.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/statemachine/qkeyeventtransition.h b/src/gui/statemachine/qkeyeventtransition.h index 08c4800..3c8295f 100644 --- a/src/gui/statemachine/qkeyeventtransition.h +++ b/src/gui/statemachine/qkeyeventtransition.h @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/statemachine/qmouseeventtransition.cpp b/src/gui/statemachine/qmouseeventtransition.cpp index ae3c407..e4e18eb 100644 --- a/src/gui/statemachine/qmouseeventtransition.cpp +++ b/src/gui/statemachine/qmouseeventtransition.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/statemachine/qmouseeventtransition.h b/src/gui/statemachine/qmouseeventtransition.h index aedc5c2..3f5f3ac 100644 --- a/src/gui/statemachine/qmouseeventtransition.h +++ b/src/gui/statemachine/qmouseeventtransition.h @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ -- cgit v0.12 From c29b54fc517be2ddff32a1c6df3a886993b786ab Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Thu, 21 May 2009 18:35:14 +1000 Subject: Fix compile error caused by reference to non-existant example. Reviewed-by: Trust Me --- examples/animation/animation.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/animation/animation.pro b/examples/animation/animation.pro index d51a89d..9a2874b 100644 --- a/examples/animation/animation.pro +++ b/examples/animation/animation.pro @@ -5,7 +5,6 @@ SUBDIRS += \ appchooser \ easing \ moveblocks \ - padnavigator-ng \ states \ stickman \ sub-attaq -- cgit v0.12 From 4ea52386e0281700e6143e0ba946314e7dd30608 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 21 May 2009 16:03:41 -0700 Subject: Removed warning Explicitly cast to integer. Reviewed-by: Shane McLaughlin --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 989a37a..a68bc8f 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -383,7 +383,7 @@ void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); d->dirtyClip = true; - const QPoint bottom = d->transform.map(QPoint(0, path.controlPointRect().y2)); + const QPoint bottom = d->transform.map(QPoint(0, int(path.controlPointRect().y2))); if (bottom.y() >= d->lastLockedHeight) d->lock(); QRasterPaintEngine::clip(path, op); -- cgit v0.12 From 6b7c7d6f0b0330571a6868f53d27a30132d4b736 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 20 May 2009 16:57:08 +0200 Subject: Use QTest::ignoreMessage() instead of custom implementation Since QTest::ignoreMessage() already exists, we should use this instead of implementing an ad hoc solution that does the same. --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 66 ++++++-------------------- 1 file changed, 14 insertions(+), 52 deletions(-) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index d033869..6b219d2 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -212,32 +212,12 @@ protected: } }; -static QtMsgType s_msgType; -static QByteArray s_msg; -static bool s_countWarnings; -static QtMsgHandler s_oldHandler; - -static void defaultErrorStateTestMessageHandler(QtMsgType type, const char *msg) -{ - s_msgType = type; - s_msg = msg; - - if (s_countWarnings) - s_oldHandler(type, msg); -} - void tst_QStateMachine::init() { - s_msg = QByteArray(); - s_msgType = QtDebugMsg; - s_countWarnings = true; - - s_oldHandler = qInstallMsgHandler(defaultErrorStateTestMessageHandler); } void tst_QStateMachine::cleanup() { - qInstallMsgHandler(s_oldHandler); } class EventTransition : public QAbstractTransition @@ -256,14 +236,13 @@ private: void tst_QStateMachine::transitionToRootState() { - s_countWarnings = false; - QStateMachine machine; QState *initialState = new QState(); machine.addState(initialState); machine.setInitialState(initialState); + QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::setTargetStates: root state cannot be target of transition"); initialState->addTransition(new EventTransition(QEvent::User, machine.rootState())); machine.start(); @@ -346,8 +325,6 @@ void tst_QStateMachine::transitionEntersParent() void tst_QStateMachine::defaultErrorState() { - s_countWarnings = false; // we expect warnings here - QStateMachine machine; QVERIFY(machine.errorState() != 0); @@ -360,14 +337,12 @@ void tst_QStateMachine::defaultErrorState() QState *childState = new QState(brokenState); childState->setObjectName("childState"); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'MyInitialState'"); + // initialState has no initial state machine.start(); QCoreApplication::processEvents(); - QCOMPARE(s_msgType, QtWarningMsg); - QCOMPARE(QString::fromLatin1(s_msg.data()), - QString::fromLatin1("Unrecoverable error detected in running state machine: Missing initial state in compound state 'MyInitialState'")); - QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'MyInitialState'")); @@ -436,8 +411,6 @@ void tst_QStateMachine::customGlobalErrorState() QCOMPARE(customErrorState->errorString, QString::fromLatin1("Missing initial state in compound state 'brokenState'")); QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'brokenState'")); - QVERIFY(s_msg.isEmpty()); - QCOMPARE(s_msgType, QtDebugMsg); } void tst_QStateMachine::customLocalErrorStateInBrokenState() @@ -453,7 +426,7 @@ void tst_QStateMachine::customLocalErrorStateInBrokenState() QState *brokenState = new QState(); brokenState->setObjectName("brokenState"); - machine.addState(brokenState); + machine.addState(brokenState); brokenState->setErrorState(customErrorState); QState *childState = new QState(brokenState); @@ -461,7 +434,7 @@ void tst_QStateMachine::customLocalErrorStateInBrokenState() initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); - machine.start(); + machine.start(); QCoreApplication::processEvents(); machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); @@ -470,19 +443,17 @@ void tst_QStateMachine::customLocalErrorStateInBrokenState() QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(customErrorState)); QCOMPARE(customErrorState->error, QStateMachine::NoInitialStateError); - QVERIFY(s_msg.isEmpty()); } void tst_QStateMachine::customLocalErrorStateInOtherState() { - s_countWarnings = false; - QStateMachine machine; CustomErrorState *customErrorState = new CustomErrorState(&machine); machine.addState(customErrorState); QState *initialState = new QState(); initialState->setObjectName("initialState"); + QTest::ignoreMessage(QtWarningMsg, "QState::setErrorState: error state cannot belong to a different state machine"); initialState->setErrorState(customErrorState); machine.addState(initialState); machine.setInitialState(initialState); @@ -497,6 +468,7 @@ void tst_QStateMachine::customLocalErrorStateInOtherState() initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'brokenState'"); machine.start(); QCoreApplication::processEvents(); @@ -505,7 +477,6 @@ void tst_QStateMachine::customLocalErrorStateInOtherState() QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(machine.errorState())); - QCOMPARE(s_msgType, QtWarningMsg); } void tst_QStateMachine::customLocalErrorStateInParentOfBrokenState() @@ -541,7 +512,6 @@ void tst_QStateMachine::customLocalErrorStateInParentOfBrokenState() QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(customErrorState)); - QVERIFY(s_msg.isEmpty()); } void tst_QStateMachine::customLocalErrorStateOverridesParent() @@ -583,7 +553,6 @@ void tst_QStateMachine::customLocalErrorStateOverridesParent() QVERIFY(machine.configuration().contains(customErrorStateForBrokenState)); QCOMPARE(customErrorStateForBrokenState->error, QStateMachine::NoInitialStateError); QCOMPARE(customErrorStateForParent->error, QStateMachine::NoError); - QVERIFY(s_msg.isEmpty()); } void tst_QStateMachine::errorStateHasChildren() @@ -622,14 +591,11 @@ void tst_QStateMachine::errorStateHasChildren() QCOMPARE(machine.configuration().count(), 2); QVERIFY(machine.configuration().contains(customErrorState)); QVERIFY(machine.configuration().contains(childOfErrorState)); - QVERIFY(s_msg.isEmpty()); } void tst_QStateMachine::errorStateHasErrors() { - s_countWarnings = false; - QStateMachine machine; CustomErrorState *customErrorState = new CustomErrorState(&machine); customErrorState->setObjectName("customErrorState"); @@ -659,21 +625,19 @@ void tst_QStateMachine::errorStateHasErrors() QCoreApplication::processEvents(); machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'customErrorState'"); QCoreApplication::processEvents(); QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(oldErrorState)); // Fall back to default QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'customErrorState'")); - - QCOMPARE(s_msgType, QtWarningMsg); } void tst_QStateMachine::errorStateIsRootState() { - s_countWarnings = false; - QStateMachine machine; + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::setErrorState: root state cannot be error state"); machine.setErrorState(machine.rootState()); QState *initialState = new QState(); @@ -694,6 +658,7 @@ void tst_QStateMachine::errorStateIsRootState() QCoreApplication::processEvents(); machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'brokenState'"); QCoreApplication::processEvents(); QCOMPARE(machine.configuration().count(), 1); @@ -774,8 +739,6 @@ void tst_QStateMachine::errorStateEntersParentFirst() void tst_QStateMachine::customErrorStateIsNull() { - s_countWarnings = false; - QStateMachine machine; QAbstractState *oldErrorState = machine.errorState(); machine.rootState()->setErrorState(0); @@ -794,12 +757,12 @@ void tst_QStateMachine::customErrorStateIsNull() QCoreApplication::processEvents(); machine.postEvent(new QEvent(QEvent::User)); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state ''"); QCoreApplication::processEvents(); QCOMPARE(machine.errorState(), reinterpret_cast(0)); QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(oldErrorState)); - QCOMPARE(s_msgType, QtWarningMsg); } void tst_QStateMachine::clearError() @@ -924,8 +887,6 @@ void tst_QStateMachine::brokenStateIsNeverEntered() void tst_QStateMachine::transitionToStateNotInGraph() { - s_countWarnings = false; - QStateMachine machine; QState *initialState = new QState(machine.rootState()); @@ -937,6 +898,7 @@ void tst_QStateMachine::transitionToStateNotInGraph() initialState->addTransition(&independentState); machine.start(); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 'initialState'"); QCoreApplication::processEvents(); QCOMPARE(machine.configuration().count(), 1); @@ -945,12 +907,11 @@ void tst_QStateMachine::transitionToStateNotInGraph() void tst_QStateMachine::customErrorStateNotInGraph() { - s_countWarnings = false; - QStateMachine machine; QState errorState; errorState.setObjectName("errorState"); + QTest::ignoreMessage(QtWarningMsg, "QState::setErrorState: error state cannot belong to a different state machine"); machine.setErrorState(&errorState); QVERIFY(&errorState != machine.errorState()); @@ -960,6 +921,7 @@ void tst_QStateMachine::customErrorStateNotInGraph() new QState(initialBrokenState); machine.start(); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'initialBrokenState'"); QCoreApplication::processEvents(); QCOMPARE(machine.configuration().count(), 1); -- cgit v0.12 From c8e632f96a942590ab9936d136dcf2f7eb17fef8 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 22 May 2009 10:01:35 +0200 Subject: configure script fix, -h should display help and not just h. Reviewed-by:cduclos --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index c882b29..32efd86 100755 --- a/configure +++ b/configure @@ -202,7 +202,7 @@ earlyArgParse() VAL=$1 fi ;; - h|help|--help|-help) + -h|help|--help|-help) if [ "$VAL" = "yes" ]; then OPT_HELP="$VAL" COMMERCIAL_USER="no" #doesn't matter we will display the help -- cgit v0.12 From ab1b7f137350d6eeafec2a64e3c25a4b02be65a9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 22 May 2009 10:05:11 +0200 Subject: Enabled the use of promoted widgets in new form templates. The form builder used for preview of the templates did not implement custom widget handling (FormBuilder::createCustomWidgets()). On encountering a promoted widget, the widget factory would then create a Widget Database entry specifying QWidget inheritance (emergency fallback) which could not be overidden later on. To fix this, moved the code for handling custom widgets from QDesignerResource to QSimpleResource and create a new formbuilder class that handles it especially for the New Form Dialog preview. Task-number: 254282 --- .../components/formeditor/qdesigner_resource.cpp | 121 +------------------ tools/designer/src/lib/shared/newformwidget.cpp | 5 +- .../src/lib/shared/qdesigner_formbuilder.cpp | 14 +++ .../src/lib/shared/qdesigner_formbuilder_p.h | 17 ++- tools/designer/src/lib/shared/qsimpleresource.cpp | 133 +++++++++++++++++++++ tools/designer/src/lib/shared/qsimpleresource_p.h | 17 +++ 6 files changed, 183 insertions(+), 124 deletions(-) diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.cpp b/tools/designer/src/components/formeditor/qdesigner_resource.cpp index 75a53b7..5f53ae2 100644 --- a/tools/designer/src/components/formeditor/qdesigner_resource.cpp +++ b/tools/designer/src/components/formeditor/qdesigner_resource.cpp @@ -743,26 +743,6 @@ void QDesignerResource::setSaveRelative(bool relative) m_resourceBuilder->setSaveRelative(relative); } -static bool addFakeMethods(const DomSlots *domSlots, QStringList &fakeSlots, QStringList &fakeSignals) -{ - if (!domSlots) - return false; - - bool rc = false; - foreach (const QString &fakeSlot, domSlots->elementSlot()) - if (fakeSlots.indexOf(fakeSlot) == -1) { - fakeSlots += fakeSlot; - rc = true; - } - - foreach (const QString &fakeSignal, domSlots->elementSignal()) - if (fakeSignals.indexOf(fakeSignal) == -1) { - fakeSignals += fakeSignal; - rc = true; - } - return rc; -} - QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget) { // Load extra info extension. This is used by Jambi for preventing @@ -1425,108 +1405,9 @@ DomLayoutItem *QDesignerResource::createDom(QLayoutItem *item, DomLayout *ui_lay return ui_item; } -static void addFakeMethodsToWidgetDataBase(const DomCustomWidget *domCustomWidget, WidgetDataBaseItem *item) -{ - const DomSlots *domSlots = domCustomWidget->elementSlots(); - if (!domSlots) - return; - - // Merge in new slots, signals - QStringList fakeSlots = item->fakeSlots(); - QStringList fakeSignals = item->fakeSignals(); - if (addFakeMethods(domSlots, fakeSlots, fakeSignals)) { - item->setFakeSlots(fakeSlots); - item->setFakeSignals(fakeSignals); - } -} - -void QDesignerResource::addCustomWidgetsToWidgetDatabase(DomCustomWidgetList& custom_widget_list) -{ - // Perform one iteration of adding the custom widgets to the database, - // looking up the base class and inheriting its data. - // Remove the succeeded custom widgets from the list. - // Classes whose base class could not be found are left in the list. - QDesignerWidgetDataBaseInterface *db = m_formWindow->core()->widgetDataBase(); - for (int i=0; i < custom_widget_list.size(); ) { - bool classInserted = false; - DomCustomWidget *custom_widget = custom_widget_list[i]; - const QString customClassName = custom_widget->elementClass(); - const QString base_class = custom_widget->elementExtends(); - QString includeFile; - IncludeType includeType = IncludeLocal; - if (const DomHeader *header = custom_widget->elementHeader()) { - includeFile = header->text(); - if (header->hasAttributeLocation() && header->attributeLocation() == QLatin1String("global")) - includeType = IncludeGlobal; - } - const bool domIsContainer = custom_widget->elementContainer(); - // Append a new item - if (base_class.isEmpty()) { - WidgetDataBaseItem *item = new WidgetDataBaseItem(customClassName); - item->setPromoted(false); - item->setGroup(QApplication::translate("Designer", "Custom Widgets")); - item->setIncludeFile(buildIncludeFile(includeFile, includeType)); - item->setContainer(domIsContainer); - item->setCustom(true); - addFakeMethodsToWidgetDataBase(custom_widget, item); - db->append(item); - custom_widget_list.removeAt(i); - classInserted = true; - } else { - // Create a new entry cloned from base class. Note that this will ignore existing - // classes, eg, plugin custom widgets. - QDesignerWidgetDataBaseItemInterface *item = - appendDerived(db, customClassName, QApplication::translate("Designer", "Promoted Widgets"), - base_class, - buildIncludeFile(includeFile, includeType), - true,true); - // Ok, base class found. - if (item) { - // Hack to accommodate for old UI-files in which "contains" is not set properly: - // Apply "contains" from DOM only if true (else, eg classes from QFrame might not accept - // dropping child widgets on them as container=false). This also allows for - // QWidget-derived stacked pages. - if (domIsContainer) - item->setContainer(domIsContainer); - - addFakeMethodsToWidgetDataBase(custom_widget, static_cast(item)); - custom_widget_list.removeAt(i); - classInserted = true; - } - } - // Skip failed item. - if (!classInserted) - i++; - } - -} void QDesignerResource::createCustomWidgets(DomCustomWidgets *dom_custom_widgets) { - if (dom_custom_widgets == 0) - return; - DomCustomWidgetList custom_widget_list = dom_custom_widgets->elementCustomWidget(); - // Attempt to insert each item derived from its base class. - // This should at most require two iterations in the event that the classes are out of order - // (derived first, max depth: promoted custom plugin = 2) - for (int iteration = 0; iteration < 2; iteration++) { - addCustomWidgetsToWidgetDatabase(custom_widget_list); - if (custom_widget_list.empty()) - return; - } - // Oops, there are classes left whose base class could not be found. - // Default them to QWidget with warnings. - const QString fallBackBaseClass = QLatin1String("QWidget"); - for (int i=0; i < custom_widget_list.size(); i++ ) { - DomCustomWidget *custom_widget = custom_widget_list[i]; - const QString customClassName = custom_widget->elementClass(); - const QString base_class = custom_widget->elementExtends(); - qDebug() << "** WARNING The base class " << base_class << " of the custom widget class " << customClassName - << " could not be found. Defaulting to " << fallBackBaseClass << '.'; - custom_widget->setElementExtends(fallBackBaseClass); - } - // One more pass. - addCustomWidgetsToWidgetDatabase(custom_widget_list); - Q_ASSERT(custom_widget_list.empty()); + QSimpleResource::handleDomCustomWidgets(core(), dom_custom_widgets); } DomTabStops *QDesignerResource::saveTabStops() diff --git a/tools/designer/src/lib/shared/newformwidget.cpp b/tools/designer/src/lib/shared/newformwidget.cpp index d79d77a..503e597 100644 --- a/tools/designer/src/lib/shared/newformwidget.cpp +++ b/tools/designer/src/lib/shared/newformwidget.cpp @@ -310,9 +310,8 @@ QImage NewFormWidget::grabForm(QDesignerFormEditorInterface *core, const QString &workingDir, const qdesigner_internal::DeviceProfile &dp) { - qdesigner_internal::QDesignerFormBuilder formBuilder(core, - qdesigner_internal::QDesignerFormBuilder::DisableScripts, - dp); + qdesigner_internal::NewFormWidgetFormBuilder + formBuilder(core, qdesigner_internal::QDesignerFormBuilder::DisableScripts, dp); if (!workingDir.isEmpty()) formBuilder.setWorkingDirectory(workingDir); diff --git a/tools/designer/src/lib/shared/qdesigner_formbuilder.cpp b/tools/designer/src/lib/shared/qdesigner_formbuilder.cpp index 6394847..b92a48d 100644 --- a/tools/designer/src/lib/shared/qdesigner_formbuilder.cpp +++ b/tools/designer/src/lib/shared/qdesigner_formbuilder.cpp @@ -473,6 +473,20 @@ QPixmap QDesignerFormBuilder::createPreviewPixmap(const QDesignerFormWindowInter return rc; } +// ---------- NewFormWidgetFormBuilder + +NewFormWidgetFormBuilder::NewFormWidgetFormBuilder(QDesignerFormEditorInterface *core, + Mode mode, + const DeviceProfile &deviceProfile) : + QDesignerFormBuilder(core, mode, deviceProfile) +{ +} + +void NewFormWidgetFormBuilder::createCustomWidgets(DomCustomWidgets *dc) +{ + QSimpleResource::handleDomCustomWidgets(core(), dc); +} + } // namespace qdesigner_internal QT_END_NAMESPACE diff --git a/tools/designer/src/lib/shared/qdesigner_formbuilder_p.h b/tools/designer/src/lib/shared/qdesigner_formbuilder_p.h index b982e1c..ee40085 100644 --- a/tools/designer/src/lib/shared/qdesigner_formbuilder_p.h +++ b/tools/designer/src/lib/shared/qdesigner_formbuilder_p.h @@ -75,7 +75,7 @@ namespace qdesigner_internal { class DesignerPixmapCache; class DesignerIconCache; -/* Form builder used for previewing forms, widget box and new form dialog. +/* Form builder used for previewing forms and widget box. * It applies the system settings to its toplevel window. */ class QDESIGNER_SHARED_EXPORT QDesignerFormBuilder: public QFormBuilder @@ -159,6 +159,21 @@ private: bool m_mainWidget; }; +// Form builder for a new form widget (preview). To allow for promoted +// widgets in the template, it implements the handling of custom widgets +// (adding of them to the widget database). + +class QDESIGNER_SHARED_EXPORT NewFormWidgetFormBuilder: public QDesignerFormBuilder { +public: + NewFormWidgetFormBuilder(QDesignerFormEditorInterface *core, + Mode mode, + const DeviceProfile &deviceProfile = DeviceProfile()); + +protected: + virtual void createCustomWidgets(DomCustomWidgets *); +}; + + } // namespace qdesigner_internal QT_END_NAMESPACE diff --git a/tools/designer/src/lib/shared/qsimpleresource.cpp b/tools/designer/src/lib/shared/qsimpleresource.cpp index 8d29002..69d48fd 100644 --- a/tools/designer/src/lib/shared/qsimpleresource.cpp +++ b/tools/designer/src/lib/shared/qsimpleresource.cpp @@ -41,6 +41,7 @@ #include "qsimpleresource_p.h" #include "widgetfactory_p.h" +#include "widgetdatabase_p.h" #include #include @@ -57,6 +58,8 @@ #include #include #include +#include + QT_BEGIN_NAMESPACE @@ -267,6 +270,136 @@ bool QSimpleResource::warningsEnabled() return m_warningsEnabled; } +// Custom widgets handling helpers + +// Add unique fake slots and signals to lists +bool QSimpleResource::addFakeMethods(const DomSlots *domSlots, QStringList &fakeSlots, QStringList &fakeSignals) +{ + if (!domSlots) + return false; + + bool rc = false; + foreach (const QString &fakeSlot, domSlots->elementSlot()) + if (fakeSlots.indexOf(fakeSlot) == -1) { + fakeSlots += fakeSlot; + rc = true; + } + + foreach (const QString &fakeSignal, domSlots->elementSignal()) + if (fakeSignals.indexOf(fakeSignal) == -1) { + fakeSignals += fakeSignal; + rc = true; + } + return rc; +} + +void QSimpleResource::addFakeMethodsToWidgetDataBase(const DomCustomWidget *domCustomWidget, WidgetDataBaseItem *item) +{ + const DomSlots *domSlots = domCustomWidget->elementSlots(); + if (!domSlots) + return; + + // Merge in new slots, signals + QStringList fakeSlots = item->fakeSlots(); + QStringList fakeSignals = item->fakeSignals(); + if (addFakeMethods(domSlots, fakeSlots, fakeSignals)) { + item->setFakeSlots(fakeSlots); + item->setFakeSignals(fakeSignals); + } +} + +// Perform one iteration of adding the custom widgets to the database, +// looking up the base class and inheriting its data. +// Remove the succeeded custom widgets from the list. +// Classes whose base class could not be found are left in the list. + +void QSimpleResource::addCustomWidgetsToWidgetDatabase(const QDesignerFormEditorInterface *core, + QList& custom_widget_list) +{ + QDesignerWidgetDataBaseInterface *db = core->widgetDataBase(); + for (int i=0; i < custom_widget_list.size(); ) { + bool classInserted = false; + DomCustomWidget *custom_widget = custom_widget_list[i]; + const QString customClassName = custom_widget->elementClass(); + const QString base_class = custom_widget->elementExtends(); + QString includeFile; + IncludeType includeType = IncludeLocal; + if (const DomHeader *header = custom_widget->elementHeader()) { + includeFile = header->text(); + if (header->hasAttributeLocation() && header->attributeLocation() == QLatin1String("global")) + includeType = IncludeGlobal; + } + const bool domIsContainer = custom_widget->elementContainer(); + // Append a new item + if (base_class.isEmpty()) { + WidgetDataBaseItem *item = new WidgetDataBaseItem(customClassName); + item->setPromoted(false); + item->setGroup(QCoreApplication::translate("Designer", "Custom Widgets")); + item->setIncludeFile(buildIncludeFile(includeFile, includeType)); + item->setContainer(domIsContainer); + item->setCustom(true); + addFakeMethodsToWidgetDataBase(custom_widget, item); + db->append(item); + custom_widget_list.removeAt(i); + classInserted = true; + } else { + // Create a new entry cloned from base class. Note that this will ignore existing + // classes, eg, plugin custom widgets. + QDesignerWidgetDataBaseItemInterface *item = + appendDerived(db, customClassName, QCoreApplication::translate("Designer", "Promoted Widgets"), + base_class, + buildIncludeFile(includeFile, includeType), + true,true); + // Ok, base class found. + if (item) { + // Hack to accommodate for old UI-files in which "container" is not set properly: + // Apply "container" from DOM only if true (else, eg classes from QFrame might not accept + // dropping child widgets on them as container=false). This also allows for + // QWidget-derived stacked pages. + if (domIsContainer) + item->setContainer(domIsContainer); + + addFakeMethodsToWidgetDataBase(custom_widget, static_cast(item)); + custom_widget_list.removeAt(i); + classInserted = true; + } + } + // Skip failed item. + if (!classInserted) + i++; + } + +} + +void QSimpleResource::handleDomCustomWidgets(const QDesignerFormEditorInterface *core, + const DomCustomWidgets *dom_custom_widgets) +{ + if (dom_custom_widgets == 0) + return; + QList custom_widget_list = dom_custom_widgets->elementCustomWidget(); + // Attempt to insert each item derived from its base class. + // This should at most require two iterations in the event that the classes are out of order + // (derived first, max depth: promoted custom plugin = 2) + for (int iteration = 0; iteration < 2; iteration++) { + addCustomWidgetsToWidgetDatabase(core, custom_widget_list); + if (custom_widget_list.empty()) + return; + } + // Oops, there are classes left whose base class could not be found. + // Default them to QWidget with warnings. + const QString fallBackBaseClass = QLatin1String("QWidget"); + for (int i=0; i < custom_widget_list.size(); i++ ) { + DomCustomWidget *custom_widget = custom_widget_list[i]; + const QString customClassName = custom_widget->elementClass(); + const QString base_class = custom_widget->elementExtends(); + qDebug() << "** WARNING The base class " << base_class << " of the custom widget class " << customClassName + << " could not be found. Defaulting to " << fallBackBaseClass << '.'; + custom_widget->setElementExtends(fallBackBaseClass); + } + // One more pass. + addCustomWidgetsToWidgetDatabase(core, custom_widget_list); +} + // ------------ FormBuilderClipboard FormBuilderClipboard::FormBuilderClipboard(QWidget *w) diff --git a/tools/designer/src/lib/shared/qsimpleresource_p.h b/tools/designer/src/lib/shared/qsimpleresource_p.h index 8d45c3c..a25cb88 100644 --- a/tools/designer/src/lib/shared/qsimpleresource_p.h +++ b/tools/designer/src/lib/shared/qsimpleresource_p.h @@ -55,15 +55,21 @@ #include "shared_global_p.h" #include "abstractformbuilder.h" +#include QT_BEGIN_NAMESPACE class DomScript; +class DomCustomWidgets; +class DomCustomWidget; +class DomSlots; class QDesignerFormEditorInterface; namespace qdesigner_internal { +class WidgetDataBaseItem; + class QDESIGNER_SHARED_EXPORT QSimpleResource : public QAbstractFormBuilder { public: @@ -92,6 +98,11 @@ public: static QString customWidgetScript(QDesignerFormEditorInterface *core, const QString &className); static bool hasCustomWidgetScript(QDesignerFormEditorInterface *core, QObject *object); + // Implementation for FormBuilder::createDomCustomWidgets() that adds + // the custom widgets to the widget database + static void handleDomCustomWidgets(const QDesignerFormEditorInterface *core, + const DomCustomWidgets *dom_custom_widgets); + protected: virtual QIcon nameToIcon(const QString &filePath, const QString &qrcPath); virtual QString iconToFilePath(const QIcon &pm) const; @@ -105,7 +116,13 @@ protected: typedef QList DomScripts; static void addScript(const QString &script, ScriptSource source, DomScripts &domScripts); + static bool addFakeMethods(const DomSlots *domSlots, QStringList &fakeSlots, QStringList &fakeSignals); + private: + static void addCustomWidgetsToWidgetDatabase(const QDesignerFormEditorInterface *core, + QList& custom_widget_list); + static void addFakeMethodsToWidgetDataBase(const DomCustomWidget *domCustomWidget, WidgetDataBaseItem *item); + static bool m_warningsEnabled; QDesignerFormEditorInterface *m_core; }; -- cgit v0.12 From 72798fc4dfc1af73cde542f9017dfec5cb020173 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 10:29:04 +0200 Subject: kill unused private functions --- src/corelib/statemachine/qabstractstate.cpp | 5 ----- src/corelib/statemachine/qabstractstate_p.h | 1 - src/corelib/statemachine/qabstracttransition.cpp | 5 ----- src/corelib/statemachine/qabstracttransition_p.h | 1 - src/corelib/statemachine/qhistorystate.cpp | 5 ----- src/corelib/statemachine/qhistorystate_p.h | 1 - 6 files changed, 18 deletions(-) diff --git a/src/corelib/statemachine/qabstractstate.cpp b/src/corelib/statemachine/qabstractstate.cpp index 7e59a7d..942722f 100644 --- a/src/corelib/statemachine/qabstractstate.cpp +++ b/src/corelib/statemachine/qabstractstate.cpp @@ -84,11 +84,6 @@ QAbstractStatePrivate *QAbstractStatePrivate::get(QAbstractState *q) return q->d_func(); } -const QAbstractStatePrivate *QAbstractStatePrivate::get(const QAbstractState *q) -{ - return q->d_func(); -} - QStateMachine *QAbstractStatePrivate::machine() const { Q_Q(const QAbstractState); diff --git a/src/corelib/statemachine/qabstractstate_p.h b/src/corelib/statemachine/qabstractstate_p.h index 1a99d6c..2aad47e 100644 --- a/src/corelib/statemachine/qabstractstate_p.h +++ b/src/corelib/statemachine/qabstractstate_p.h @@ -69,7 +69,6 @@ public: QAbstractStatePrivate(); static QAbstractStatePrivate *get(QAbstractState *q); - static const QAbstractStatePrivate *get(const QAbstractState *q); QStateMachine *machine() const; diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp index 68423cb..dfcafeb 100644 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -108,11 +108,6 @@ QAbstractTransitionPrivate *QAbstractTransitionPrivate::get(QAbstractTransition return q->d_func(); } -const QAbstractTransitionPrivate *QAbstractTransitionPrivate::get(const QAbstractTransition *q) -{ - return q->d_func(); -} - QStateMachine *QAbstractTransitionPrivate::machine() const { Q_Q(const QAbstractTransition); diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h index a6db220..f067984 100644 --- a/src/corelib/statemachine/qabstracttransition_p.h +++ b/src/corelib/statemachine/qabstracttransition_p.h @@ -73,7 +73,6 @@ public: QAbstractTransitionPrivate(); static QAbstractTransitionPrivate *get(QAbstractTransition *q); - static const QAbstractTransitionPrivate *get(const QAbstractTransition *q); bool callEventTest(QEvent *e); void callOnTransition(QEvent *e); diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp index d1b2391..517faa8 100644 --- a/src/corelib/statemachine/qhistorystate.cpp +++ b/src/corelib/statemachine/qhistorystate.cpp @@ -126,11 +126,6 @@ QHistoryStatePrivate *QHistoryStatePrivate::get(QHistoryState *q) return q->d_func(); } -const QHistoryStatePrivate *QHistoryStatePrivate::get(const QHistoryState *q) -{ - return q->d_func(); -} - /*! Constructs a new shallow history state with the given \a parent state. */ diff --git a/src/corelib/statemachine/qhistorystate_p.h b/src/corelib/statemachine/qhistorystate_p.h index 2f17496..5aaa64c 100644 --- a/src/corelib/statemachine/qhistorystate_p.h +++ b/src/corelib/statemachine/qhistorystate_p.h @@ -68,7 +68,6 @@ public: QHistoryStatePrivate(); static QHistoryStatePrivate *get(QHistoryState *q); - static const QHistoryStatePrivate *get(const QHistoryState *q); QAbstractState *defaultState; QHistoryState::HistoryType historyType; -- cgit v0.12 From 5cd9be6c2702ce1f4292003ac3e864f08a0311f3 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Fri, 22 May 2009 10:49:32 +0200 Subject: Fix toolbutton text incorrectly clipped on windows In 4.5 the toolbutton icon rendering was changed somewhat and the bottom line of text for tool buttons icons with TextUnderIcon set is incorrectly clipped on Windows. The style reserves only 5 pixels but tries to use 6 pixels for text and icon spacing, hence we adjust the text rect one pixel up. This should be safe considering the fact that we have a margin on both sides of the icon already and avoids actually moving the icon positioning. Task-number: 252554 Reviewed-by: trond --- src/gui/styles/qcommonstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 3cae08a..f3d1537 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -1693,7 +1693,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { pr.setHeight(pmSize.height() + 6); - tr.adjust(0, pr.height(), 0, -3); + tr.adjust(0, pr.height() - 1, 0, -3); pr.translate(shiftX, shiftY); if (!hasArrow) { drawItemPixmap(p, pr, Qt::AlignCenter, pm); -- cgit v0.12 From 8502f76e820ab79181a1b8ac54c8431b298a2023 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 22 May 2009 10:53:31 +0200 Subject: Mark data as static, use fetch-and-store instead of test-and-set Mark the objectCount and mutex-pool as static as they won't ever be externed. Use fetch-and-store zero instead of test-and-set from current value to zero. --- src/corelib/kernel/qobject.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index cfd8493..1e9e284 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -92,8 +92,8 @@ static int *queuedConnectionTypes(const QList &typeNames) return types; } -QBasicAtomicPointer signalSlotMutexes = Q_BASIC_ATOMIC_INITIALIZER(0); -QBasicAtomicInt objectCount = Q_BASIC_ATOMIC_INITIALIZER(0); +static QBasicAtomicPointer signalSlotMutexes = Q_BASIC_ATOMIC_INITIALIZER(0); +static QBasicAtomicInt objectCount = Q_BASIC_ATOMIC_INITIALIZER(0); /** \internal * mutex to be locked when accessing the connectionlists or the senders list @@ -117,8 +117,7 @@ extern "C" Q_CORE_EXPORT void qt_addObject(QObject *) extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) { if(!objectCount.deref()) { - QMutexPool *old = signalSlotMutexes; - signalSlotMutexes.testAndSetAcquire(old, 0); + QMutexPool *old = signalSlotMutexes.fetchAndStoreAcquire(0); delete old; } } -- cgit v0.12 From 31fcf8e77f8ef8020edfbfd224cf6e68cb0450bf Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 22 May 2009 11:01:39 +0200 Subject: Update the QMutexPool API to be more like QMutex If we ever decide to make this class public, the interfaces should be similar. --- src/corelib/thread/qmutexpool.cpp | 14 +++++++------- src/corelib/thread/qmutexpool_p.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp index 96a9940..77a3cca 100644 --- a/src/corelib/thread/qmutexpool.cpp +++ b/src/corelib/thread/qmutexpool.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE // qt_global_mutexpool is here for backwards compatability only, // use QMutexpool::instance() in new clode. Q_CORE_EXPORT QMutexPool *qt_global_mutexpool = 0; -Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (true)) +Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (QMutex::Recursive)) /*! \class QMutexPool @@ -88,15 +88,15 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (true)) */ /*! - Constructs a QMutexPool, reserving space for \a size QMutexes. If - \a recursive is true, all QMutexes in the pool will be recursive - mutexes; otherwise they will all be non-recursive (the default). + Constructs a QMutexPool, reserving space for \a size QMutexes. All + mutexes in the pool are created with \a recursionMode. By default, + all mutexes are non-recursive. The QMutexes are created when needed, and deleted when the QMutexPool is destructed. */ -QMutexPool::QMutexPool(bool recursive, int size) - : mutexes(size), count(size), recurs(recursive) +QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size) + : mutexes(size), count(size), recursionMode(recursionMode) { for (int index = 0; index < count; ++index) { mutexes[index] = 0; @@ -134,7 +134,7 @@ QMutex *QMutexPool::get(const void *address) if (!mutexes[index]) { // mutex not created, create one - QMutex *newMutex = new QMutex(recurs ? QMutex::Recursive : QMutex::NonRecursive); + QMutex *newMutex = new QMutex(recursionMode); if (!mutexes[index].testAndSetOrdered(0, newMutex)) delete newMutex; } diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h index 1009ebb..4c1e32c 100644 --- a/src/corelib/thread/qmutexpool_p.h +++ b/src/corelib/thread/qmutexpool_p.h @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QMutexPool { public: - explicit QMutexPool(bool recursive = false, int size = 128); + explicit QMutexPool(QMutex::RecursionMode recursionMode = QMutex::NonRecursive, int size = 128); ~QMutexPool(); QMutex *get(const void *address); @@ -74,7 +74,7 @@ public: private: QVarLengthArray, 128> mutexes; int count; - bool recurs; + QMutex::RecursionMode recursionMode; }; extern Q_CORE_EXPORT QMutexPool *qt_global_mutexpool; -- cgit v0.12 From 6b7736e5cc352f1326989eee8dd9ef87f2b9a486 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Fri, 22 May 2009 11:06:28 +0200 Subject: Doc - removing the constraint on font size. Reviewed-By: David Boddie --- tools/qdoc3/test/classic.css | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css index 8e9eb78..e700e0a 100644 --- a/tools/qdoc3/test/classic.css +++ b/tools/qdoc3/test/classic.css @@ -1,9 +1,6 @@ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Arial, Geneva, Helvetica, sans-serif; } -BODY,TD { - font-size: 90%; -} H1 { text-align: center; font-size: 160%; -- cgit v0.12 From 8ad5020940f10d4ecc5c5e8b3b9656531cb84ef3 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 20 May 2009 16:38:47 +0200 Subject: Add properties to QGraphicsItem to change the transformations component With the new properties it is possible to easily animate. Setting a transform using setTransform is incompatible with thoses properties. Accessing thoses propeties if you set previously a transform will give you the default values. Acknowledged-by: Code made with Andreas. Documentation written with Thierry. This still need a more in depth code review and documentation review. But it is urgent to commit now because the Animation API integration depends on it. --- src/gui/graphicsview/qgraphicsitem.cpp | 431 +++++++++++++++++++-- src/gui/graphicsview/qgraphicsitem.h | 41 +- src/gui/graphicsview/qgraphicsitem_p.h | 79 +++- src/gui/graphicsview/qgraphicswidget.h | 9 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 88 +++++ tests/benchmarks/qgraphicsitem/qgraphicsitem.pro | 6 + .../benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp | 170 ++++++++ 7 files changed, 780 insertions(+), 44 deletions(-) create mode 100644 tests/benchmarks/qgraphicsitem/qgraphicsitem.pro create mode 100644 tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 72b832a..b7e88f4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -130,12 +130,18 @@ \img graphicsview-parentchild.png + \section Transformation + QGraphicsItem supports affine transformations in addition to its base position, pos(). To change the item's transformation, you can either pass - a transformation matrix to setTransform(), or call one of the convenience - functions rotate(), scale(), translate(), or shear(). Item transformations - accumulate from parent to child, so if both a parent and child item are - rotated 90 degrees, the child's total transformation will be 180 degrees. + a transformation matrix to setTransform(), or set the different transformation + properties (transformOrigin, x/y/zRotation, x/yScale, horizontal/verticalShear). + Note that setting the transformation matrix conflicts with using the properties. + Setting the properties will overwrite the transformation set with setTransform, + and using setTransform will reset the properties. + + Item transformations accumulate from parent to child, so if both a parent and child + item are rotated 90 degrees, the child's total transformation will be 180 degrees. Similarly, if the item's parent is scaled to 2x its original size, its children will also be twice as large. An item's transformation does not affect its own local geometry; all geometry functions (e.g., contains(), @@ -146,6 +152,22 @@ and scenePos(), which returns its position in scene coordinates. To reset an item's matrix, call resetTransform(). + The order you set the transformation properties does not affect the resulting transformation + The resulting transformation is always computed in the following order + + \code + [Origin] [RotateX] [RotateY] [RotateZ] [Shear] [Scale] [-Origin] + \endcode + + So the transformation is equivalent to the following code + + \code + QTransform().translate(xOrigin, yOrigin).rotate(xRotation, Qt::XAxis).rotate(yRotation, Qt::YAxis).rotate(zRotation, Qt::ZAxis) + .shear(horizontalShear, verticalShear).scale(xScale, yScale).translate(-xOrigin, -yOrigin); + \endcode + + \section Painting + The paint() function is called by QGraphicsView to paint the item's contents. The item has no background or default fill of its own; whatever is behind the item will shine through all areas that are not explicitly @@ -161,6 +183,8 @@ high z-values. Stacking order applies to sibling items; parents are always drawn before their children. + \section Events + QGraphicsItem receives events from QGraphicsScene through the virtual function sceneEvent(). This function distributes the most common events to a set of convenience event handlers: @@ -186,6 +210,8 @@ by the virtual function sceneEventFilter(). You can remove item event filters by calling removeSceneEventFilter(). + \section Custom Data + Sometimes it's useful to register custom data with an item, be it a custom item, or a standard item. You can call setData() on any item to store data in it using a key-value pair (the key being an integer, and the value is a @@ -338,16 +364,17 @@ \value ItemTransformChange The item's transformation matrix changes. This notification is only sent when the item's local transformation matrix - changes (i.e., as a result of calling setTransform(), or one of the - convenience transformation functions, such as rotate()). The value + changes (i.e., as a result of calling setTransform(). The value argument is the new matrix (i.e., a QTransform); to get the old matrix, - call transform(). Do not call setTransform() or any of the transformation - convenience functions in itemChange() as this notification is delivered; + call transform(). Do not call setTransform() or set any of the transformation + properties in itemChange() as this notification is delivered; instead, you can return the new matrix from itemChange(). + This notification is not sent if you change the transformation properties. \value ItemTransformHasChanged The item's transformation matrix has - changed. This notification is only sent after the item's local - trasformation matrix has changed. The value argument is the new matrix + changed either because setTransform is called, or one of the transformation + properties is changed. This notification is only sent after the item's local + transformation matrix has changed. The value argument is the new matrix (same as transform()), and QGraphicsItem ignores the return value for this notification (i.e., a read-only notification). @@ -2559,8 +2586,13 @@ QMatrix QGraphicsItem::matrix() const /*! \since 4.3 - Returns this item's transformation matrix. If no matrix has been set, the - identity matrix is returned. + Returns this item's transformation matrix. + + Either the one set by setTransform, or the resulting transformation from + all the transfmation properties + + If no matrix or transformation property has been set, the + identity matrix is returned. \sa setTransform(), sceneTransform() */ @@ -2568,10 +2600,307 @@ QTransform QGraphicsItem::transform() const { if (!d_ptr->hasTransform) return QTransform(); + if (d_ptr->hasDecomposedTransform && d_ptr->dirtyTransform) { + QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + QTransform x; + decomposed->generateTransform(&x); + QVariant v(x); + d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, v); + d_ptr->dirtyTransform = 0; + d_ptr->dirtyTransformComponents = 1; + const_cast(this)->itemChange(ItemTransformHasChanged, v); + return x; + } return qVariantValue(d_ptr->extra(QGraphicsItemPrivate::ExtraTransform)); } /*! + \property QGraphicsItem::xRotation + + \since 4.6 + + This property holds the rotation angle in degrees around the X axis + + The default is 0 + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, this function return the default value. + + \sa {Transformations} +*/ +qreal QGraphicsItem::xRotation() const +{ + return d_ptr->decomposedTransform()->xRotation; +} + +void QGraphicsItem::setXRotation(qreal angle) +{ + if (!d_ptr->dirtyTransform) { + d_ptr->fullUpdateHelper(true); + prepareGeometryChange(); + } + QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + decomposed->xRotation = angle; + if (!d_ptr->dirtyTransform) + d_ptr->invalidateSceneTransformCache(); + d_ptr->dirtyTransform = 1; + d_ptr->hasTransform = 1; +} + +/*! + \property QGraphicsItem::yRotation + + \since 4.6 + + This property holds the rotation angle in degrees around the Y axis + + The default is 0 + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, this function return the default value. + + \sa {Transformations} +*/ +qreal QGraphicsItem::yRotation() const +{ + return d_ptr->decomposedTransform()->yRotation; +} + +void QGraphicsItem::setYRotation(qreal angle) +{ + if (!d_ptr->dirtyTransform) { + d_ptr->fullUpdateHelper(true); + prepareGeometryChange(); + } + QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + decomposed->yRotation = angle; + if (!d_ptr->dirtyTransform) + d_ptr->invalidateSceneTransformCache(); + d_ptr->dirtyTransform = 1; + d_ptr->hasTransform = 1; +} + +/*! + \property QGraphicsItem::zRotation + + \since 4.6 + + This property holds the rotation angle in degrees around the Z axis + + The default is 0 + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, this function return the default value. + + \sa {Transformations} +*/ +qreal QGraphicsItem::zRotation() const +{ + return d_ptr->decomposedTransform()->zRotation; +} + +void QGraphicsItem::setZRotation(qreal angle) +{ + if (!d_ptr->dirtyTransform) { + d_ptr->fullUpdateHelper(true); + prepareGeometryChange(); + } + QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + decomposed->zRotation = angle; + if (!d_ptr->dirtyTransform) + d_ptr->invalidateSceneTransformCache(); + d_ptr->dirtyTransform = 1; + d_ptr->hasTransform = 1; +} + +void QGraphicsItem::setRotation(qreal x, qreal y, qreal z) +{ + setXRotation(x); + setYRotation(y); + setZRotation(z); +} + +/*! + \property QGraphicsItem::xScale + + \since 4.6 + + This property holds the scale factor on the X axis. + + The default is 1 + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, this function return the default value. + + \sa {Transformations} +*/ +qreal QGraphicsItem::xScale() const +{ + return d_ptr->decomposedTransform()->xScale; +} + +void QGraphicsItem::setXScale(qreal factor) +{ + if (!d_ptr->dirtyTransform) { + d_ptr->fullUpdateHelper(true); + prepareGeometryChange(); + } + QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + decomposed->xScale = factor; + if (!d_ptr->dirtyTransform) + d_ptr->invalidateSceneTransformCache(); + d_ptr->dirtyTransform = 1; + d_ptr->hasTransform = 1; +} + +/*! + \property QGraphicsItem::yScale + + \since 4.6 + + This property holds the scale factor on the Y axis. + + The default is 1 + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, this function return the default value. + + \sa {Transformations} +*/ +qreal QGraphicsItem::yScale() const +{ + return d_ptr->decomposedTransform()->yScale; +} + +void QGraphicsItem::setYScale(qreal factor) +{ + if (!d_ptr->dirtyTransform) { + d_ptr->fullUpdateHelper(true); + prepareGeometryChange(); + } + QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + decomposed->yScale = factor; + if (!d_ptr->dirtyTransform) + d_ptr->invalidateSceneTransformCache(); + d_ptr->dirtyTransform = 1; + d_ptr->hasTransform = 1; +} + +void QGraphicsItem::setScale(qreal sx, qreal sy) +{ + setXScale(sx); + setYScale(sy); +} + +/*! + \property QGraphicsItem::horizontalShear + + \since 4.6 + + This property holds the horizontal shear. + + The default is 0. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, this function return the default value. + + \sa {Transformations} +*/ +qreal QGraphicsItem::horizontalShear() const +{ + return d_ptr->decomposedTransform()->horizontalShear; +} + +void QGraphicsItem::setHorizontalShear(qreal shear) +{ + if (!d_ptr->dirtyTransform) { + d_ptr->fullUpdateHelper(true); + prepareGeometryChange(); + } + QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + decomposed->horizontalShear = shear; + if (!d_ptr->dirtyTransform) + d_ptr->invalidateSceneTransformCache(); + d_ptr->dirtyTransform = 1; + d_ptr->hasTransform = 1; +} + +/*! + \property QGraphicsItem::verticalShear + + \since 4.6 + + This property holds the vertical shear. + + The default is 0. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, this function return the default value. + + \sa {Transformations} +*/ +qreal QGraphicsItem::verticalShear() const +{ + return d_ptr->decomposedTransform()->verticalShear; +} + +void QGraphicsItem::setVerticalShear(qreal shear) +{ + if (!d_ptr->dirtyTransform) { + d_ptr->fullUpdateHelper(true); + prepareGeometryChange(); + } + QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + decomposed->verticalShear = shear; + if (!d_ptr->dirtyTransform) + d_ptr->invalidateSceneTransformCache(); + d_ptr->dirtyTransform = 1; + d_ptr->hasTransform = 1; +} + +void QGraphicsItem::setShear(qreal sh, qreal sv) +{ + setHorizontalShear(sh); + setVerticalShear(sv); +} + +/*! + \property QGraphicsItem::transformOrigin + + \since 4.6 + + This property holds the transformation origin for the transformation properties. + This does not apply to the transformation set by setTransform. + + The default is QPointF(0,0). + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, this function return the default value. + + \sa {Transformations} +*/ +QPointF QGraphicsItem::transformOrigin() const +{ + const QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + return QPointF(decomposed->xOrigin, decomposed->yOrigin); +} + +void QGraphicsItem::setTransformOrigin(const QPointF &origin) +{ + if (!d_ptr->dirtyTransform) { + d_ptr->fullUpdateHelper(true); + prepareGeometryChange(); + } + QGraphicsItemPrivate::DecomposedTransform *decomposed = d_ptr->decomposedTransform(); + decomposed->xOrigin = origin.x(); + decomposed->yOrigin = origin.y(); + if (!d_ptr->dirtyTransform) + d_ptr->invalidateSceneTransformCache(); + d_ptr->dirtyTransform = 1; + d_ptr->hasTransform = 1; +} + +/*! \obsolete Use sceneTransform() instead. @@ -2846,7 +3175,7 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co Use setTransform() instead. - \sa transform(), rotate(), scale(), shear(), translate(), {The Graphics View Coordinate System} + \sa transform(), {The Graphics View Coordinate System} */ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) { @@ -2872,6 +3201,8 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) d_ptr->hasTransform = !newTransform.isIdentity(); d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform); d_ptr->invalidateSceneTransformCache(); + if (d_ptr->hasDecomposedTransform) + d_ptr->dirtyTransform = 1; // Send post-notification. // NB! We have to change the value from QMatrix to QTransform. @@ -2894,7 +3225,10 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) to map an item coordiate to a scene coordinate, or mapFromScene() to map from scene coordinates to item coordinates. - \sa transform(), rotate(), scale(), shear(), translate(), {The Graphics View Coordinate System} + \warning using this function conflicts with using the transformation properties. + If you set a transformation, getting the properties will return default values. + + \sa transform(), setRotation(), setScale(), setShear(), setTransformOrigin() {The Graphics View Coordinate System} */ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine) { @@ -2920,6 +3254,8 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine) d_ptr->hasTransform = !newTransform.isIdentity(); d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform); d_ptr->invalidateSceneTransformCache(); + if (d_ptr->hasDecomposedTransform) + d_ptr->dirtyTransform = 1; // Send post-notification. itemChange(ItemTransformHasChanged, newTransformVariant); @@ -2938,8 +3274,9 @@ void QGraphicsItem::resetMatrix() /*! \since 4.3 - Resets this item's transformation matrix to the identity matrix. This is - equivalent to calling \c setTransform(QTransform()). + Resets this item's transformation matrix to the identity matrix or + all the transformation properties to their default values. + This is equivalent to calling \c setTransform(QTransform()). \sa setTransform(), transform() */ @@ -2949,6 +3286,9 @@ void QGraphicsItem::resetTransform() } /*! + \obsolete + Use setZRotation() instead + Rotates the current item transformation \a angle degrees clockwise around its origin. To translate around an arbitrary point (x, y), you need to combine translation and rotation with setTransform(). @@ -2957,6 +3297,9 @@ void QGraphicsItem::resetTransform() \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 6 + \warning using this function conflicts with using the transformation properties. + Getting those properties after using this function will return default values. + \sa setTransform(), transform(), scale(), shear(), translate() */ void QGraphicsItem::rotate(qreal angle) @@ -2965,6 +3308,9 @@ void QGraphicsItem::rotate(qreal angle) } /*! + \obsolete + Use setScale() instead + Scales the current item transformation by (\a sx, \a sy) around its origin. To scale from an arbitrary point (x, y), you need to combine translation and scaling with setTransform(). @@ -2973,7 +3319,10 @@ void QGraphicsItem::rotate(qreal angle) \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 7 - \sa setTransform(), transform(), rotate(), shear(), translate() + \warning using this function conflicts with using the transformation properties. + Getting those properties after using this function will return default values. + + \sa setTransform(), transform() */ void QGraphicsItem::scale(qreal sx, qreal sy) { @@ -2981,9 +3330,15 @@ void QGraphicsItem::scale(qreal sx, qreal sy) } /*! + \obsolete + Use setShear instead. + Shears the current item transformation by (\a sh, \a sv). - \sa setTransform(), transform(), rotate(), scale(), translate() + \warning using this function conflicts with using the transformation properties. + Getting those properties after using this function will return default values. + + \sa setTransform(), transform() */ void QGraphicsItem::shear(qreal sh, qreal sv) { @@ -2991,13 +3346,19 @@ void QGraphicsItem::shear(qreal sh, qreal sv) } /*! + \obsolete + Use setPos() or setTransformOrigin() instead. + Translates the current item transformation by (\a dx, \a dy). If all you want is to move an item, you should call moveBy() or setPos() instead; this function changes the item's translation, which is conceptually separate from its position. - \sa setTransform(), transform(), rotate(), scale(), shear() + \warning using this function conflicts with using the transformation properties. + Getting those properties after using this function will return default values. + + \sa setTransform(), transform() */ void QGraphicsItem::translate(qreal dx, qreal dy) { @@ -3121,7 +3482,7 @@ QRectF QGraphicsItem::childrenBoundingRect() const Although the item's shape can be arbitrary, the bounding rect is always rectangular, and it is unaffected by the items' - transformation (scale(), rotate(), etc.). + transformation. If you want to change the item's bounding rectangle, you must first call prepareGeometryChange(). This notifies the scene of the imminent change, @@ -8143,19 +8504,19 @@ bool QGraphicsTextItem::sceneEvent(QEvent *event) void QGraphicsTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { if ((QGraphicsItem::d_ptr->flags & (ItemIsSelectable | ItemIsMovable)) - && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) { - // User left-pressed on edge of selectable/movable item, use - // base impl. - dd->useDefaultImpl = true; + && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) { + // User left-pressed on edge of selectable/movable item, use + // base impl. + dd->useDefaultImpl = true; } else if (event->buttons() == event->button() - && dd->control->textInteractionFlags() == Qt::NoTextInteraction) { - // User pressed first button on non-interactive item. - dd->useDefaultImpl = true; + && dd->control->textInteractionFlags() == Qt::NoTextInteraction) { + // User pressed first button on non-interactive item. + dd->useDefaultImpl = true; } if (dd->useDefaultImpl) { QGraphicsItem::mousePressEvent(event); - if (!event->isAccepted()) - dd->useDefaultImpl = false; + if (!event->isAccepted()) + dd->useDefaultImpl = false; return; } dd->sendControlEvent(event); @@ -8180,14 +8541,14 @@ void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (dd->useDefaultImpl) { QGraphicsItem::mouseReleaseEvent(event); - if (dd->control->textInteractionFlags() == Qt::NoTextInteraction - && !event->buttons()) { - // User released last button on non-interactive item. + if (dd->control->textInteractionFlags() == Qt::NoTextInteraction + && !event->buttons()) { + // User released last button on non-interactive item. dd->useDefaultImpl = false; - } else if ((event->buttons() & Qt::LeftButton) == 0) { - // User released the left button on an interactive item. + } else if ((event->buttons() & Qt::LeftButton) == 0) { + // User released the left button on an interactive item. dd->useDefaultImpl = false; - } + } return; } dd->sendControlEvent(event); diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 0a0179e..f6ee197 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -241,11 +241,41 @@ public: QTransform itemTransform(const QGraphicsItem *other, bool *ok = 0) const; void setTransform(const QTransform &matrix, bool combine = false); void resetTransform(); - - void rotate(qreal angle); - void scale(qreal sx, qreal sy); - void shear(qreal sh, qreal sv); - void translate(qreal dx, qreal dy); + + void rotate(qreal angle); // ### obsolete + void scale(qreal sx, qreal sy); // ### obsolete + void shear(qreal sh, qreal sv); // ### obsolete + void translate(qreal dx, qreal dy); // ### obsolete + + qreal xRotation() const; + void setXRotation(qreal angle); + + qreal yRotation() const; + void setYRotation(qreal angle); + + qreal zRotation() const; + void setZRotation(qreal angle); + void setRotation(qreal x, qreal y, qreal z); + + qreal xScale() const; + void setXScale(qreal factor); + + qreal yScale() const; + void setYScale(qreal factor); + void setScale(qreal sx, qreal sy); + + qreal horizontalShear() const; + void setHorizontalShear(qreal shear); + + qreal verticalShear() const; + void setVerticalShear(qreal shear); + void setShear(qreal sh, qreal sv); + + QPointF transformOrigin() const; + void setTransformOrigin(const QPointF &origin); + inline void setTransformOrigin(qreal x, qreal y) + { setTransformOrigin(QPointF(x,y)); } + virtual void advance(int phase); // Stacking order @@ -1015,4 +1045,3 @@ QT_END_NAMESPACE QT_END_HEADER #endif // QGRAPHICSITEM_H - diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 820ef04..cebc8ca 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -56,6 +56,8 @@ #include "qgraphicsitem.h" #include "qpixmapcache.h" +#include + #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW QT_BEGIN_NAMESPACE @@ -101,7 +103,8 @@ public: ExtraMaxDeviceCoordCacheSize, ExtraBoundingRegionGranularity, ExtraOpacity, - ExtraEffectiveOpacity + ExtraEffectiveOpacity, + ExtraDecomposedTransform }; enum AncestorFlag { @@ -145,6 +148,9 @@ public: inSetPosHelper(0), flags(0), allChildrenCombineOpacity(1), + hasDecomposedTransform(0), + dirtyTransform(0), + dirtyTransformComponents(0), globalStackingOrder(-1), sceneTransformIndex(-1), q_ptr(0) @@ -331,15 +337,84 @@ public: // New 32 bits quint32 flags : 10; quint32 allChildrenCombineOpacity : 1; - quint32 padding : 21; // feel free to use + quint32 hasDecomposedTransform : 1; + quint32 dirtyTransform : 1; + quint32 dirtyTransformComponents : 1; + quint32 padding : 18; // feel free to use // Optional stacking order int globalStackingOrder; int sceneTransformIndex; + struct DecomposedTransform; + DecomposedTransform *decomposedTransform() const + { + QGraphicsItemPrivate *that = const_cast(this); + DecomposedTransform *decomposed; + if (hasDecomposedTransform) { + decomposed = qVariantValue(extra(ExtraDecomposedTransform)); + } else { + decomposed = new DecomposedTransform; + that->setExtra(ExtraDecomposedTransform, qVariantFromValue(decomposed)); + that->hasDecomposedTransform = 1; + if (!dirtyTransformComponents) + decomposed->reset(); + } + if (dirtyTransformComponents) { + decomposed->initFrom(q_ptr->transform()); + that->dirtyTransformComponents = 0; + } + return decomposed; + } + + struct DecomposedTransform { + qreal xScale; + qreal yScale; + qreal xRotation; + qreal yRotation; + qreal zRotation; + qreal horizontalShear; + qreal verticalShear; + qreal xOrigin; + qreal yOrigin; + + inline void reset() + { + xScale = 1.0; + yScale = 1.0; + xRotation = 0.0; + yRotation = 0.0; + zRotation = 0.0; + horizontalShear = 0.0; + verticalShear = 0.0; + xOrigin = 0.0; + yOrigin = 0.0; + } + + inline void initFrom(const QTransform &x) + { + reset(); + // ### decompose transform + Q_UNUSED(x); + } + + inline void generateTransform(QTransform *x) const + { + x->translate(xOrigin, yOrigin); + x->rotate(xRotation, Qt::XAxis); + x->rotate(yRotation, Qt::YAxis); + x->rotate(zRotation, Qt::ZAxis); + x->shear(horizontalShear, verticalShear); + x->scale(xScale, yScale); + x->translate(-xOrigin, -yOrigin); + } + }; + QGraphicsItem *q_ptr; }; +Q_DECLARE_METATYPE(QGraphicsItemPrivate::DecomposedTransform *) + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 34f1c5f..a5c9068 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -81,7 +81,14 @@ class Q_GUI_EXPORT QGraphicsWidget : public QObject, public QGraphicsItem, publi Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) Q_PROPERTY(QPointF pos READ pos WRITE setPos) Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) - + Q_PROPERTY(QPointF transformOrigin READ transformOrigin WRITE setTransformOrigin) + Q_PROPERTY(qreal xRotation READ xRotation WRITE setXRotation) + Q_PROPERTY(qreal yRotation READ yRotation WRITE setYRotation) + Q_PROPERTY(qreal zRotation READ zRotation WRITE setZRotation) + Q_PROPERTY(qreal xScale READ xScale WRITE setXScale) + Q_PROPERTY(qreal yScale READ yScale WRITE setYScale) + Q_PROPERTY(qreal horizontalShear READ horizontalShear WRITE setHorizontalShear) + Q_PROPERTY(qreal verticalShear READ verticalShear WRITE setVerticalShear) public: QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); ~QGraphicsWidget(); diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index b3ae60a..d41b3b4 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -219,6 +219,8 @@ private slots: void updateCachedItemAfterMove(); void deviceTransform_data(); void deviceTransform(); + void setTransformProperties_data(); + void setTransformProperties(); // task specific tests below me void task141694_textItemEnsureVisible(); @@ -6390,5 +6392,91 @@ void tst_QGraphicsItem::deviceTransform() QCOMPARE(rect3->deviceTransform(deviceX).map(QPointF(50, 50)), mapResult3); } +void tst_QGraphicsItem::setTransformProperties_data() +{ + QTest::addColumn("origin"); + QTest::addColumn("rotationX"); + QTest::addColumn("rotationY"); + QTest::addColumn("rotationZ"); + QTest::addColumn("scaleX"); + QTest::addColumn("scaleY"); + QTest::addColumn("shearX"); + QTest::addColumn("shearY"); + + QTest::newRow("nothing") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) + << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + + QTest::newRow("rotationZ") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(42.2) + << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + + QTest::newRow("rotationXY") << QPointF() << qreal(12.5) << qreal(53.6) << qreal(0.0) + << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + + QTest::newRow("rotationXYZ") << QPointF() << qreal(-25) << qreal(12) << qreal(556) + << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + + QTest::newRow("rotationXYZ dicentred") << QPointF(-53, 25.2) + << qreal(-2578.2) << qreal(4565.2) << qreal(56) + << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + + QTest::newRow("Scale") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) + << qreal(6) << qreal(0.5) << qreal(0.0) << qreal(0.0); + + QTest::newRow("Shear") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) + << qreal(0.0) << qreal(0.0) << qreal(2.2) << qreal(0.5); + + QTest::newRow("Scale and Shear") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) + << qreal(5.2) << qreal(2.1) << qreal(5.2) << qreal(5.5); + + QTest::newRow("Everything") << QPointF() << qreal(41) << qreal(-23) << qreal(0.56) + << qreal(8.2) << qreal(-0.2) << qreal(-12) << qreal(-0.8); + + QTest::newRow("Everything dicentred") << QPointF(qreal(22.3), qreal(-56.2)) << qreal(-175) << qreal(196) << qreal(-1260) + << qreal(4) << qreal(2) << qreal(2.56) << qreal(0.8); +} + +void tst_QGraphicsItem::setTransformProperties() +{ + QFETCH(QPointF,origin); + QFETCH(qreal,rotationX); + QFETCH(qreal,rotationY); + QFETCH(qreal,rotationZ); + QFETCH(qreal,scaleX); + QFETCH(qreal,scaleY); + QFETCH(qreal,shearX); + QFETCH(qreal,shearY); + + QTransform result; + result.translate(origin.x(), origin.y()); + result.rotate(rotationX, Qt::XAxis); + result.rotate(rotationY, Qt::YAxis); + result.rotate(rotationZ, Qt::ZAxis); + result.shear(shearX, shearY); + result.scale(scaleX, scaleY); + result.translate(-origin.x(), -origin.y()); + + QGraphicsScene scene; + QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0, 0, 100, 100)); + scene.addItem(item); + item->setPos(100, 100); + + item->setRotation(rotationX, rotationY, rotationZ); + item->setScale(scaleX, scaleY); + item->setShear(shearX, shearY); + item->setTransformOrigin(origin); + + QCOMPARE(item->xRotation(), rotationX); + QCOMPARE(item->yRotation(), rotationY); + QCOMPARE(item->zRotation(), rotationZ); + QCOMPARE(item->xScale(), scaleX); + QCOMPARE(item->yScale(), scaleY); + QCOMPARE(item->horizontalShear(), shearX); + QCOMPARE(item->verticalShear(), shearY); + QCOMPARE(item->transformOrigin(), origin); + + QCOMPARE(result, item->transform()); +} + + QTEST_MAIN(tst_QGraphicsItem) #include "tst_qgraphicsitem.moc" diff --git a/tests/benchmarks/qgraphicsitem/qgraphicsitem.pro b/tests/benchmarks/qgraphicsitem/qgraphicsitem.pro new file mode 100644 index 0000000..c8fc07b --- /dev/null +++ b/tests/benchmarks/qgraphicsitem/qgraphicsitem.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qgraphicsitem + +SOURCES += tst_qgraphicsitem.cpp + diff --git a/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp new file mode 100644 index 0000000..68e3aa1 --- /dev/null +++ b/tests/benchmarks/qgraphicsitem/tst_qgraphicsitem.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include +#include +#include +#include + +//TESTED_FILES= + +class tst_QGraphicsItem : public QObject +{ + Q_OBJECT + +public: + tst_QGraphicsItem(); + virtual ~tst_QGraphicsItem(); + +public slots: + void init(); + void cleanup(); + +private slots: + void setPos_data(); + void setPos(); + void setTransform_data(); + void setTransform(); + void rotate(); + void scale(); + void shear(); + void translate(); + void setRotation(); + void setRotationXYZ(); +}; + +tst_QGraphicsItem::tst_QGraphicsItem() +{ +} + +tst_QGraphicsItem::~tst_QGraphicsItem() +{ +} + +void tst_QGraphicsItem::init() +{ +} + +void tst_QGraphicsItem::cleanup() +{ +} + +void tst_QGraphicsItem::setPos_data() +{ + QTest::addColumn("pos"); + + QTest::newRow("0, 0") << QPointF(0, 0); + QTest::newRow("10, 10") << QPointF(10, 10); + QTest::newRow("-10, -10") << QPointF(-10, -10); +} + +void tst_QGraphicsItem::setPos() +{ + QFETCH(QPointF, pos); + + QGraphicsScene scene; + QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100)); + + QBENCHMARK { + rect->setPos(10, 10); + rect->transform(); // prevent lazy optimizing + } +} + +void tst_QGraphicsItem::setTransform_data() +{ + QTest::addColumn("transform"); + + QTest::newRow("id") << QTransform(); + QTest::newRow("rotate 45z") << QTransform().rotate(45); + QTest::newRow("scale 2x2") << QTransform().scale(2, 2); + QTest::newRow("translate 100, 100") << QTransform().translate(100, 100); + QTest::newRow("rotate 45x 45y 45z") << QTransform().rotate(45, Qt::XAxis) + .rotate(45, Qt::YAxis).rotate(45, Qt::ZAxis); +} + +void tst_QGraphicsItem::setTransform() +{ + QFETCH(QTransform, transform); + + QGraphicsScene scene; + QGraphicsRectItem *item = scene.addRect(QRectF(0, 0, 100, 100)); + + QBENCHMARK { + item->setTransform(transform); + item->transform(); // prevent lazy optimizing + } +} + +void tst_QGraphicsItem::rotate() +{ + QGraphicsScene scene; + QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100)); + + QBENCHMARK { + item->rotate(45); + item->transform(); // prevent lazy optimizing + } +} + +void tst_QGraphicsItem::scale() +{ + QGraphicsScene scene; + QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100)); + + QBENCHMARK { + item->scale(2, 2); + item->transform(); // prevent lazy optimizing + } +} + +void tst_QGraphicsItem::shear() +{ + QGraphicsScene scene; + QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100)); + + QBENCHMARK { + item->shear(1.5, 1.5); + item->transform(); // prevent lazy optimizing + } +} + +void tst_QGraphicsItem::translate() +{ + QGraphicsScene scene; + QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100)); + + QBENCHMARK { + item->translate(100, 100); + item->transform(); // prevent lazy optimizing + } +} + +void tst_QGraphicsItem::setRotation() +{ + QGraphicsScene scene; + QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100)); + + QBENCHMARK { + item->setXRotation(45); + item->transform(); // prevent lazy optimizing + } +} + +void tst_QGraphicsItem::setRotationXYZ() +{ + QGraphicsScene scene; + QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100)); + + QBENCHMARK { + item->setRotation(45, 45, 45); + item->transform(); // prevent lazy optimizing + } +} + +QTEST_MAIN(tst_QGraphicsItem) +#include "tst_qgraphicsitem.moc" -- cgit v0.12 From 308a105bf6ae6eb5702440728428a96b5806b085 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Fri, 22 May 2009 11:08:38 +0200 Subject: Revert "Ignore GCC warning of unsafe floating point comparisons." MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 30f7edc0aab629499b74263391ae529ad31b2ff8. There is no way to restore float-equal warning using the pragma trick. This means (as it was mentioned in the said commit log) anyone that includes qtransform.h will be forced to deal with float-equal. Reviewed-by: Samuel Rødal --- src/gui/painting/qtransform.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index 4a33969..c76409b 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -255,13 +255,6 @@ inline qreal QTransform::dy() const return affine._dy; } -#if defined(Q_CC_GNU) -# define Q_CC_GNU_VERSION (((__GNUC__)<<16)|((__GNUC_MINOR__)<<8)|(__GNUC_PATCHLEVEL__)) -# if Q_CC_GNU_VERSION >= 0x040201 -# pragma GCC diagnostic ignored "-Wfloat-equal" -# endif -#endif - inline QTransform &QTransform::operator*=(qreal num) { if (num == 1.) @@ -318,13 +311,6 @@ inline QTransform &QTransform::operator-=(qreal num) return *this; } -#if defined(Q_CC_GNU_VERSION) -# if Q_CC_GNU_VERSION >= 0x040201 -# pragma GCC diagnostic warning "-Wfloat-equal" -# endif -# undef Q_CC_GNU_VERSION -#endif - /****** stream functions *******************/ Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTransform &); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTransform &); -- cgit v0.12 From 815a8c4a297cde2b8f778c4afa36958e324f8ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Fri, 22 May 2009 11:17:29 +0200 Subject: Fixed an issue with text drawing to QImages on Mac/Cocoa. We currently don't support subpixel hinting when drawing text to a QImage on Mac. The alpha map that is returned by the font engine is a plain 8 bit gray mask, which means we have to switch off subpixel hinting when we draw the glyph for caching. Task-number: 249178 Reviewed-by: Samuel --- src/gui/text/qfontengine_mac.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 425cab2..d397e4a 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -553,7 +553,9 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) 8, im.bytesPerLine(), colorspace, cgflags); CGContextSetFontSize(ctx, fontDef.pixelSize); - CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias)); + CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold + && !(fontDef.styleStrategy & QFont::NoAntialias)); + CGContextSetShouldSmoothFonts(ctx, false); CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); -- cgit v0.12 From 5eec99263c9133e3a8177f463c537c75dfe9215b Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 11:24:33 +0200 Subject: add more tests --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 89 ++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 6b219d2..05c45ca 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -985,6 +985,7 @@ void tst_QStateMachine::rootState() QVERIFY(qobject_cast(machine.rootState()) != 0); QCOMPARE(qobject_cast(machine.rootState())->parentState(), (QState*)0); QCOMPARE(machine.rootState()->parent(), (QObject*)&machine); + QCOMPARE(machine.rootState()->machine(), &machine); QState *s1 = new QState(machine.rootState()); QCOMPARE(s1->parentState(), machine.rootState()); @@ -1006,7 +1007,9 @@ void tst_QStateMachine::addAndRemoveState() QState *s1 = new QState(); QCOMPARE(s1->parentState(), (QState*)0); + QCOMPARE(s1->machine(), (QStateMachine*)0); machine.addState(s1); + QCOMPARE(s1->machine(), &machine); QCOMPARE(s1->parentState(), machine.rootState()); QCOMPARE(root_d->childStates().size(), 2); QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); @@ -1063,8 +1066,29 @@ void tst_QStateMachine::stateEntryAndExit() TestState *s2 = new TestState(machine.rootState()); QFinalState *s3 = new QFinalState(machine.rootState()); + TestTransition *t = new TestTransition(s2); + QCOMPARE(t->machine(), (QStateMachine*)0); + QCOMPARE(t->sourceState(), (QState*)0); + QCOMPARE(t->targetState(), s2); + QCOMPARE(t->targetStates().size(), 1); + QCOMPARE(t->targetStates().at(0), s2); + t->setTargetState(0); + QCOMPARE(t->targetState(), (QState*)0); + QVERIFY(t->targetStates().isEmpty()); + t->setTargetState(s2); + QCOMPARE(t->targetState(), s2); + QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::setTargetStates: target state(s) cannot be null"); + t->setTargetStates(QList() << 0); + QCOMPARE(t->targetState(), s2); + t->setTargetStates(QList() << s2); + QCOMPARE(t->targetState(), s2); + QCOMPARE(t->targetStates().size(), 1); + QCOMPARE(t->targetStates().at(0), s2); QCOMPARE(s1->addTransition(t), (QAbstractTransition*)t); + QCOMPARE(t->sourceState(), s1); + QCOMPARE(t->machine(), &machine); + { QAbstractTransition *trans = s2->addTransition(s3); QVERIFY(trans != 0); @@ -1081,6 +1105,7 @@ void tst_QStateMachine::stateEntryAndExit() QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); QSignalSpy finishedSpy(&machine, SIGNAL(finished())); machine.setInitialState(s1); + QCOMPARE(machine.initialState(), (QAbstractState*)s1); QVERIFY(machine.configuration().isEmpty()); globalTick = 0; QVERIFY(!machine.isRunning()); @@ -1222,9 +1247,22 @@ void tst_QStateMachine::assignPropertyWithAnimation() s2->assignProperty(&obj, "foo", 456); s2->assignProperty(&obj, "bar", 789); QAbstractTransition *trans = s1->addTransition(s2); + QVERIFY(trans->animations().isEmpty()); + QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::addAnimation: cannot add null animation"); + trans->addAnimation(0); QPropertyAnimation anim(&obj, "foo"); anim.setDuration(250); trans->addAnimation(&anim); + QCOMPARE(trans->animations().size(), 1); + QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim); + QCOMPARE(anim.parent(), (QObject*)0); + QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::removeAnimation: cannot remove null animation"); + trans->removeAnimation(0); + trans->removeAnimation(&anim); + QVERIFY(trans->animations().isEmpty()); + trans->addAnimation(&anim); + QCOMPARE(trans->animations().size(), 1); + QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim); QFinalState *s3 = new QFinalState(machine.rootState()); s2->addTransition(s2, SIGNAL(polished()), s3); @@ -1548,8 +1586,8 @@ Q_SIGNALS: class TestSignalTransition : public QSignalTransition { public: - TestSignalTransition() - : QSignalTransition() {} + TestSignalTransition(QState *sourceState = 0) + : QSignalTransition(sourceState) {} TestSignalTransition(QObject *sender, const char *signal, QAbstractState *target) : QSignalTransition(sender, signal, QList() << target) {} @@ -1722,15 +1760,23 @@ void tst_QStateMachine::signalTransitions() void tst_QStateMachine::eventTransitions() { QPushButton button; - { + for (int x = 0; x < 2; ++x) { QStateMachine machine; QState *s0 = new QState(machine.rootState()); QFinalState *s1 = new QFinalState(machine.rootState()); - QMouseEventTransition *trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, Qt::LeftButton); + QMouseEventTransition *trans; + if (x == 0) { + trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, Qt::LeftButton); + QCOMPARE(trans->targetState(), (QAbstractState*)0); + trans->setTargetState(s1); + } else { + trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, + Qt::LeftButton, QList() << s1); + } QCOMPARE(trans->eventType(), QEvent::MouseButtonPress); QCOMPARE(trans->button(), Qt::LeftButton); - trans->setTargetState(s1); + QCOMPARE(trans->targetState(), (QAbstractState*)s1); s0->addTransition(trans); QSignalSpy finishedSpy(&machine, SIGNAL(finished())); @@ -1739,25 +1785,40 @@ void tst_QStateMachine::eventTransitions() QCoreApplication::processEvents(); QTest::mousePress(&button, Qt::LeftButton); - QCoreApplication::processEvents(); - QTRY_COMPARE(finishedSpy.count(), 1); QTest::mousePress(&button, Qt::LeftButton); + + trans->setEventType(QEvent::MouseButtonRelease); + QCOMPARE(trans->eventType(), QEvent::MouseButtonRelease); + machine.start(); + QCoreApplication::processEvents(); + QTest::mouseRelease(&button, Qt::LeftButton); + QTRY_COMPARE(finishedSpy.count(), 2); } - { + for (int x = 0; x < 3; ++x) { QStateMachine machine; QState *s0 = new QState(machine.rootState()); QFinalState *s1 = new QFinalState(machine.rootState()); - QEventTransition *trans = new QEventTransition(); - QCOMPARE(trans->eventObject(), (QObject*)0); - QCOMPARE(trans->eventType(), QEvent::None); - trans->setEventObject(&button); + QEventTransition *trans; + if (x == 0) { + trans = new QEventTransition(); + QCOMPARE(trans->eventObject(), (QObject*)0); + QCOMPARE(trans->eventType(), QEvent::None); + trans->setEventObject(&button); + trans->setEventType(QEvent::MouseButtonPress); + trans->setTargetState(s1); + } else if (x == 1) { + trans = new QEventTransition(&button, QEvent::MouseButtonPress); + trans->setTargetState(s1); + } else { + trans = new QEventTransition(&button, QEvent::MouseButtonPress, + QList() << s1); + } QCOMPARE(trans->eventObject(), (QObject*)&button); - trans->setEventType(QEvent::MouseButtonPress); QCOMPARE(trans->eventType(), QEvent::MouseButtonPress); - trans->setTargetState(s1); + QCOMPARE(trans->targetState(), (QAbstractState*)s1); s0->addTransition(trans); QSignalSpy finishedSpy(&machine, SIGNAL(finished())); -- cgit v0.12 From 6c1d7e57ee8d7988ab9592e4112b1f28fd1d03ce Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 4 May 2009 20:49:41 +0200 Subject: Fixed strict aliasing breaks with sockaddr_XXX structs. This case it was possible to fix by using a union of the types when we actually declare the variable. Besides, this avoids a bunch of #ifdef for IPv6 functionality. Reviewed-By: Oswald Buddenhagen --- src/network/socket/qnativesocketengine_p.h | 9 ++++ src/network/socket/qnativesocketengine_unix.cpp | 61 ++++++++----------------- 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h index 3366f2d..825c333 100644 --- a/src/network/socket/qnativesocketengine_p.h +++ b/src/network/socket/qnativesocketengine_p.h @@ -90,6 +90,15 @@ static inline int qt_socket_socket(int domain, int type, int protocol) #endif +union qt_sockaddr { + sockaddr a; + sockaddr_in a4; +#if !defined(QT_NO_IPV6) + sockaddr_in6 a6; +#endif + sockaddr_storage storage; +}; + class QNativeSocketEnginePrivate; class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index cc372a6..2b11e8e 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -114,36 +114,34 @@ static void qt_ignore_sigpipe() Extracts the port and address from a sockaddr, and stores them in \a port and \a addr if they are non-null. */ -static inline void qt_socket_getPortAndAddress(struct sockaddr *sa, quint16 *port, QHostAddress *addr) +static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *port, QHostAddress *addr) { #if !defined(QT_NO_IPV6) - if (sa->sa_family == AF_INET6) { - struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; + if (s->a.sa_family == AF_INET6) { Q_IPV6ADDR tmp; - memcpy(&tmp, &sa6->sin6_addr.s6_addr, sizeof(tmp)); + memcpy(&tmp, &s->a6.sin6_addr.s6_addr, sizeof(tmp)); if (addr) { QHostAddress tmpAddress; tmpAddress.setAddress(tmp); *addr = tmpAddress; #ifndef QT_NO_IPV6IFNAME char scopeid[IFNAMSIZ]; - if (::if_indextoname(sa6->sin6_scope_id, scopeid) > 0) { + if (::if_indextoname(s->a6.sin6_scope_id, scopeid) > 0) { addr->setScopeId(QLatin1String(scopeid)); } else #endif - addr->setScopeId(QString::number(sa6->sin6_scope_id)); + addr->setScopeId(QString::number(s->a6.sin6_scope_id)); } if (port) - *port = ntohs(sa6->sin6_port); + *port = ntohs(s->a6.sin6_port); return; } #endif - struct sockaddr_in *sa4 = (struct sockaddr_in *)sa; if (port) - *port = ntohs(sa4->sin_port); + *port = ntohs(s->a4.sin_port); if (addr) { QHostAddress tmpAddress; - tmpAddress.setAddress(ntohl(sa4->sin_addr.s_addr)); + tmpAddress.setAddress(ntohl(s->a4.sin_addr.s_addr)); *addr = tmpAddress; } } @@ -521,26 +519,16 @@ qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const { // Create a sockaddr struct and reset its port number. -#if !defined(QT_NO_IPV6) - struct sockaddr_storage storage; - sockaddr_in6 *storagePtrIPv6 = reinterpret_cast(&storage); - storagePtrIPv6->sin6_port = 0; -#else - struct sockaddr storage; -#endif - sockaddr *storagePtr = reinterpret_cast(&storage); - storagePtr->sa_family = 0; - - sockaddr_in *storagePtrIPv4 = reinterpret_cast(&storage); - storagePtrIPv4->sin_port = 0; + qt_sockaddr storage; QT_SOCKLEN_T storageSize = sizeof(storage); + memset(&storage, 0, storageSize); // Peek 0 bytes into the next message. The size of the message may // well be 0, so we can't check recvfrom's return value. ssize_t readBytes; do { char c; - readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, storagePtr, &storageSize); + readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, &storage.a, &storageSize); } while (readBytes == -1 && errno == EINTR); // If there's no error, or if our buffer was too small, there must be a @@ -583,11 +571,7 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxSize, QHostAddress *address, quint16 *port) { -#if !defined(QT_NO_IPV6) - struct sockaddr_storage aa; -#else - struct sockaddr_in aa; -#endif + qt_sockaddr aa; memset(&aa, 0, sizeof(aa)); QT_SOCKLEN_T sz; sz = sizeof(aa); @@ -596,13 +580,13 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS do { char c; recvFromResult = ::recvfrom(socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1, - 0, (struct sockaddr *)&aa, &sz); + 0, &aa.a, &sz); } while (recvFromResult == -1 && errno == EINTR); if (recvFromResult == -1) { setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString); } else if (port || address) { - qt_socket_getPortAndAddress((struct sockaddr *) &aa, port, address); + qt_socket_getPortAndAddress(&aa, port, address); } #if defined (QNATIVESOCKETENGINE_DEBUG) @@ -682,21 +666,16 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() if (socketDescriptor == -1) return false; -#if !defined(QT_NO_IPV6) - struct sockaddr_storage sa; -#else - struct sockaddr_in sa; -#endif - struct sockaddr *sockAddrPtr = (struct sockaddr *) &sa; + qt_sockaddr sa; QT_SOCKLEN_T sockAddrSize = sizeof(sa); // Determine local address memset(&sa, 0, sizeof(sa)); - if (::getsockname(socketDescriptor, sockAddrPtr, &sockAddrSize) == 0) { - qt_socket_getPortAndAddress(sockAddrPtr, &localPort, &localAddress); + if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) { + qt_socket_getPortAndAddress(&sa, &localPort, &localAddress); // Determine protocol family - switch (sockAddrPtr->sa_family) { + switch (sa.a.sa_family) { case AF_INET: socketProtocol = QAbstractSocket::IPv4Protocol; break; @@ -716,8 +695,8 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() } // Determine the remote address - if (!::getpeername(socketDescriptor, sockAddrPtr, &sockAddrSize)) - qt_socket_getPortAndAddress(sockAddrPtr, &peerPort, &peerAddress); + if (!::getpeername(socketDescriptor, &sa.a, &sockAddrSize)) + qt_socket_getPortAndAddress(&sa, &peerPort, &peerAddress); // Determine the socket type (UDP/TCP) int value = 0; -- cgit v0.12 From 5a62f2add2cba756a132f94a114d770285f01d9c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 19 May 2009 18:10:06 +0200 Subject: Add an autotest to check that the network test server works MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test verifies that the network test server is behaving as expected. I think I caught all the services we need testing in the server, but there's still some work to be done: 1) verify that the FTP files are there where they're supposed to be 2) verify that FTP writable areas are writable 3) verify that the HTTP server has the correct files too 4) verify that the HTTP server requests credentials for the protected area 5) attempt to do NTLM authentication to verify the password (probably can't be done with netChat) 6) add Windows SMB tests (//qt-test-server/etc.) 7) add SQL tests (connecting to the SQL server ports) It would be good as well if we could not use QtNetwork. If you break QtNetwork, this test breaks too, so we don't know where the fault is. However, rewriting networking code will add another source of bugs (same for the NTLM authentication). Reviewed-By: JoĂ£o Abecasis --- tests/auto/_networkselftest/_networkselftest.pro | 6 + .../auto/_networkselftest/tst_networkselftest.cpp | 592 +++++++++++++++++++++ tests/auto/auto.pro | 3 +- 3 files changed, 600 insertions(+), 1 deletion(-) create mode 100644 tests/auto/_networkselftest/_networkselftest.pro create mode 100644 tests/auto/_networkselftest/tst_networkselftest.cpp diff --git a/tests/auto/_networkselftest/_networkselftest.pro b/tests/auto/_networkselftest/_networkselftest.pro new file mode 100644 index 0000000..9e2ad0e --- /dev/null +++ b/tests/auto/_networkselftest/_networkselftest.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES += tst_networkselftest.cpp +QT = core network +DEFINES += SRCDIR=\\\"$$PWD\\\" + diff --git a/tests/auto/_networkselftest/tst_networkselftest.cpp b/tests/auto/_networkselftest/tst_networkselftest.cpp new file mode 100644 index 0000000..dab4433 --- /dev/null +++ b/tests/auto/_networkselftest/tst_networkselftest.cpp @@ -0,0 +1,592 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "../network-settings.h" + +class tst_NetworkSelfTest: public QObject +{ + Q_OBJECT +private slots: + void hostTest(); + void dnsResolution_data(); + void dnsResolution(); + void serverReachability(); + void remotePortsOpen_data(); + void remotePortsOpen(); + + // specific protocol tests + void ftpServer(); + void imapServer(); + void httpServer(); + void httpsServer(); + void httpProxy(); + void httpProxyBasicAuth(); + void httpProxyNtlmAuth(); + void socks5Proxy(); + void socks5ProxyAuth(); +}; + +class Chat +{ +public: + enum Type { + Reconnect, + Send, + Expect, + SkipBytes, + DiscardUntil, + DiscardUntilDisconnect, + Disconnect, + RemoteDisconnect, + StartEncryption + }; + Chat(Type t, const QByteArray &d) + : data(d), type(t) + { + } + Chat(Type t, int val = 0) + : value(val), type(t) + { + } + + static inline Chat send(const QByteArray &data) + { return Chat(Send, data); } + static inline Chat expect(const QByteArray &data) + { return Chat(Expect, data); } + static inline Chat discardUntil(const QByteArray &data) + { return Chat(DiscardUntil, data); } + static inline Chat skipBytes(int count) + { return Chat(SkipBytes, count); } + + QByteArray data; + int value; + Type type; +}; + +static QString prettyByteArray(const QByteArray &array) +{ + // any control chars? + QString result; + result.reserve(array.length() + array.length() / 3); + for (int i = 0; i < array.length(); ++i) { + char c = array.at(i); + switch (c) { + case '\n': + result += "\\n"; + continue; + case '\r': + result += "\\r"; + continue; + case '\t': + result += "\\t"; + continue; + case '"': + result += "\\\""; + continue; + default: + break; + } + + if (c < 0x20 || uchar(c) >= 0x7f) { + result += '\\'; + result += QString::number(uchar(c), 8); + } else { + result += c; + } + } + return result; +} + +static bool doSocketRead(QTcpSocket *socket, int minBytesAvailable, int timeout = 2000) +{ + QTime timer; + timer.start(); + forever { + if (socket->bytesAvailable() >= minBytesAvailable) + return true; + if (socket->state() == QAbstractSocket::UnconnectedState + || timer.elapsed() >= timeout) + return false; + if (!socket->waitForReadyRead(timeout - timer.elapsed())) + return false; + } +} + +static bool doSocketFlush(QTcpSocket *socket, int timeout = 2000) +{ +#ifndef QT_NO_OPENSSL + QSslSocket *sslSocket = qobject_cast(socket); +#endif + QTime timer; + timer.start(); + forever { + if (socket->bytesToWrite() == 0 +#ifndef QT_NO_OPENSSL + && sslSocket->encryptedBytesToWrite() == 0 +#endif + ) + return true; + if (socket->state() == QAbstractSocket::UnconnectedState + || timer.elapsed() >= timeout) + return false; + if (!socket->waitForBytesWritten(timeout - timer.elapsed())) + return false; + } +} + +static void netChat(int port, const QList &chat) +{ +#ifndef QT_NO_OPENSSL + QSslSocket socket; +#else + QTcpSocket socket; +#endif + + socket.connectToHost(QtNetworkSettings::serverName(), port); + qDebug() << 0 << "Connecting to server on port" << port; + QVERIFY2(socket.waitForConnected(10000), + QString("Failed to connect to server in step 0: %1").arg(socket.errorString()).toLocal8Bit()); + + // now start the chat + QList::ConstIterator it = chat.constBegin(); + for (int i = 1; it != chat.constEnd(); ++it, ++i) { + if (it->type != Chat::Reconnect + && socket.state() != QAbstractSocket::ConnectedState + && socket.state() != QAbstractSocket::ClosingState) + QFAIL(QString("Internal error: socket is in invalid state %1 in step %2") + .arg(socket.state()).arg(i).toLocal8Bit()); + + switch (it->type) { + case Chat::Expect: { + qDebug() << i << "Expecting" << prettyByteArray(it->data); + if (!doSocketRead(&socket, it->data.length())) + QFAIL(QString("Failed to receive data in step %1: timeout").arg(i).toLocal8Bit()); + + // pop that many bytes off the socket + QByteArray received = socket.read(it->data.length()); + + // is it what we expected? + QVERIFY2(received == it->data, + QString("Did not receive expected data in step %1: data received was:\n%2") + .arg(i).arg(prettyByteArray(received)).toLocal8Bit()); + + break; + } + + case Chat::DiscardUntil: + qDebug() << i << "Discarding until" << prettyByteArray(it->data); + while (true) { + // scan the buffer until we have our string + if (!doSocketRead(&socket, it->data.length())) + QFAIL(QString("Failed to receive data in step %1: timeout").arg(i).toLocal8Bit()); + + QByteArray buffer; + buffer.resize(socket.bytesAvailable()); + socket.peek(buffer.data(), socket.bytesAvailable()); + + int pos = buffer.indexOf(it->data); + if (pos == -1) { + // data not found, keep trying + continue; + } + + buffer = socket.read(pos + it->data.length()); + qDebug() << i << "Discarded" << prettyByteArray(buffer); + break; + } + break; + + case Chat::SkipBytes: { + qDebug() << i << "Skipping" << it->value << "bytes"; + if (!doSocketRead(&socket, it->value)) + QFAIL(QString("Failed to receive data in step %1: timeout").arg(i).toLocal8Bit()); + + // now discard the bytes + QByteArray buffer = socket.read(it->value); + qDebug() << i << "Skipped" << prettyByteArray(buffer); + break; + } + + case Chat::Send: { + qDebug() << i << "Sending" << prettyByteArray(it->data); + socket.write(it->data); + if (!doSocketFlush(&socket)) { + QVERIFY2(socket.state() == QAbstractSocket::ConnectedState, + QString("Socket disconnected while sending data in step %1").arg(i).toLocal8Bit()); + QFAIL(QString("Failed to send data in step %1: timeout").arg(i).toLocal8Bit()); + } + break; + } + + case Chat::Disconnect: + qDebug() << i << "Disconnecting from host"; + socket.disconnectFromHost(); + + // is this the last command? + if (it + 1 != chat.constEnd()) + break; + + // fall through: + case Chat::RemoteDisconnect: + case Chat::DiscardUntilDisconnect: + qDebug() << i << "Waiting for remote disconnect"; + if (socket.state() != QAbstractSocket::UnconnectedState) + socket.waitForDisconnected(10000); + QVERIFY2(socket.state() == QAbstractSocket::UnconnectedState, + QString("Socket did not disconnect as expected in step %1").arg(i).toLocal8Bit()); + + // any data left? + if (it->type == Chat::DiscardUntilDisconnect) { + QByteArray buffer = socket.readAll(); + qDebug() << i << "Discarded in the process:" << prettyByteArray(buffer); + } + + if (socket.bytesAvailable() != 0) + QFAIL(QString("Unexpected bytes still on buffer when disconnecting in step %1:\n%2") + .arg(i).arg(prettyByteArray(socket.readAll())).toLocal8Bit()); + break; + + case Chat::Reconnect: + qDebug() << i << "Reconnecting to server on port" << port; + socket.connectToHost(QtNetworkSettings::serverName(), port); + QVERIFY2(socket.waitForConnected(10000), + QString("Failed to reconnect to server in step %1: %2").arg(i).arg(socket.errorString()).toLocal8Bit()); + break; + + case Chat::StartEncryption: +#ifdef QT_NO_OPENSSL + QFAIL("Internal error: SSL required for this test"); +#else + qDebug() << i << "Starting client encryption"; + socket.ignoreSslErrors(); + socket.startClientEncryption(); + QVERIFY2(socket.waitForEncrypted(5000), + QString("Failed to start client encryption in step %1: %2").arg(i) + .arg(socket.errorString()).toLocal8Bit()); + break; +#endif + } + } +} + +void tst_NetworkSelfTest::hostTest() +{ + // this is a localhost self-test + QHostInfo localhost = QHostInfo::fromName("localhost"); + QCOMPARE(localhost.error(), QHostInfo::NoError); + QVERIFY(!localhost.addresses().isEmpty()); + + QTcpServer server; + QVERIFY(server.listen()); + + QTcpSocket socket; + socket.connectToHost("127.0.0.1", server.serverPort()); + QVERIFY(socket.waitForConnected(10000)); +} + +void tst_NetworkSelfTest::dnsResolution_data() +{ + QTest::addColumn("hostName"); + QTest::newRow("local-name") << QtNetworkSettings::serverLocalName(); + QTest::newRow("fqdn") << QtNetworkSettings::serverName(); +} + +void tst_NetworkSelfTest::dnsResolution() +{ + QFETCH(QString, hostName); + QHostInfo resolved = QHostInfo::fromName(hostName); + QVERIFY2(resolved.error() == QHostInfo::NoError, + QString("Failed to resolve hostname %1: %2").arg(hostName, resolved.errorString()).toLocal8Bit()); +} + +void tst_NetworkSelfTest::serverReachability() +{ + // check that we get a proper error connecting to port 1 + QTcpSocket socket; + socket.connectToHost(QtNetworkSettings::serverName(), 1); + socket.waitForConnected(10000); + QVERIFY2(socket.state() == QAbstractSocket::UnconnectedState, "Socket connected unexpectedly!"); + QVERIFY2(socket.error() == QAbstractSocket::ConnectionRefusedError, + QString("Could not reach server: %1").arg(socket.errorString()).toLocal8Bit()); +} + +void tst_NetworkSelfTest::remotePortsOpen_data() +{ + QTest::addColumn("portNumber"); + QTest::newRow("ftp") << 21; + QTest::newRow("ssh") << 22; + QTest::newRow("imap") << 143; + QTest::newRow("http") << 80; + QTest::newRow("https") << 443; + QTest::newRow("http-proxy") << 3128; + QTest::newRow("http-proxy-auth-basic") << 3129; + QTest::newRow("http-proxy-auth-ntlm") << 3130; + QTest::newRow("socks5-proxy") << 1080; + QTest::newRow("socks5-proxy-auth") << 1081; +} + +void tst_NetworkSelfTest::remotePortsOpen() +{ + QFETCH(int, portNumber); + QTcpSocket socket; + socket.connectToHost(QtNetworkSettings::serverName(), portNumber); + + if (!socket.waitForConnected(10000)) { + if (socket.error() == QAbstractSocket::SocketTimeoutError) + QFAIL(QString("Network timeout connecting to the server on port %1").arg(portNumber).toLocal8Bit()); + else + QFAIL(QString("Error connecting to server on port %1: %2").arg(portNumber).arg(socket.errorString()).toLocal8Bit()); + } + QVERIFY(socket.state() == QAbstractSocket::ConnectedState); +} + +static QList ftpChat() +{ + return QList() << Chat::expect("220") + << Chat::discardUntil("\r\n") + << Chat::send("USER anonymous\r\n") + << Chat::expect("331") + << Chat::discardUntil("\r\n") + << Chat::send("PASS user@hostname\r\n") + << Chat::expect("230") + << Chat::discardUntil("\r\n") + << Chat::send("QUIT\r\n") + << Chat::expect("221") + << Chat::discardUntil("\r\n") + << Chat::RemoteDisconnect; +} + +void tst_NetworkSelfTest::ftpServer() +{ + netChat(21, ftpChat()); +} + +void tst_NetworkSelfTest::imapServer() +{ + netChat(143, QList() + << Chat::expect("* OK ") + << Chat::discardUntil("\r\n") + << Chat::send("1 CAPABILITY\r\n") + << Chat::expect("* CAPABILITY ") + << Chat::discardUntil("1 OK") + << Chat::discardUntil("\r\n") + << Chat::send("2 LOGOUT\r\n") + << Chat::discardUntil("2 OK") + << Chat::discardUntil("\r\n") + << Chat::RemoteDisconnect); +} + +void tst_NetworkSelfTest::httpServer() +{ + netChat(80, QList() + // HTTP/0.9 chat: + << Chat::send("GET /\r\n") + << Chat::DiscardUntilDisconnect + + // HTTP/1.0 chat: + << Chat::Reconnect + << Chat::send("GET / HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect + + // HTTP/1.0 POST: + << Chat::Reconnect + << Chat::send("POST / HTTP/1.0\r\n" + "Content-Length: 5\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n" + "Hello") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect + ); +} + +void tst_NetworkSelfTest::httpsServer() +{ +#ifndef QT_NO_OPENSSL + netChat(443, QList() + << Chat::StartEncryption + << Chat::send("GET / HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect); +#else + QSKIP("SSL not enabled, cannot test"); +#endif +} + +void tst_NetworkSelfTest::httpProxy() +{ + netChat(3128, QList() + // proxy GET + << Chat::send("GET http://" + QtNetworkSettings::serverName().toLatin1() + "/ HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Proxy-connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect + + // proxy CONNECT + << Chat::Reconnect + << Chat::send("CONNECT " + QtNetworkSettings::serverName().toLatin1() + ":21 HTTP/1.0\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::discardUntil("\r\n\r\n") + << ftpChat()); +} + +void tst_NetworkSelfTest::httpProxyBasicAuth() +{ + netChat(3129, QList() + // test auth required response + << Chat::send("GET http://" + QtNetworkSettings::serverName().toLatin1() + "/ HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Proxy-connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("407 ") + << Chat::discardUntil("\r\nProxy-Authenticate: Basic realm=\"") + << Chat::DiscardUntilDisconnect + + // now try sending our credentials + << Chat::Reconnect + << Chat::send("GET http://" + QtNetworkSettings::serverName().toLatin1() + "/ HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Proxy-connection: close\r\n" + "Proxy-Authorization: Basic cXNvY2tzdGVzdDpwYXNzd29yZA==\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect); +} + +void tst_NetworkSelfTest::httpProxyNtlmAuth() +{ + netChat(3130, QList() + // test auth required response + << Chat::send("GET http://" + QtNetworkSettings::serverName().toLatin1() + "/ HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Proxy-connection: keep-alive\r\n" // NTLM auth will disconnect + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("407 ") + << Chat::discardUntil("\r\nProxy-Authenticate: NTLM\r\n") + << Chat::DiscardUntilDisconnect + ); +} + +// SOCKSv5 is a binary protocol +static const char handshakeNoAuth[] = "\5\1\0"; +static const char handshakeOkNoAuth[] = "\5\0"; +static const char handshakeAuthPassword[] = "\5\1\2\1\12qsockstest\10password"; +static const char handshakeOkPasswdAuth[] = "\5\2\1\0"; +static const char handshakeAuthNotOk[] = "\5\377"; +static const char connect1[] = "\5\1\0\1\177\0\0\1\0\25"; // Connect IPv4 127.0.0.1 port 21 +static const char connect2[] = "\5\1\0\3\11localhost\0\25"; // Connect hostname localhost 21 +static const char connected[] = "\5\0\0"; + +void tst_NetworkSelfTest::socks5Proxy() +{ + netChat(1080, QList() + // IP address connection + << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) + << Chat::expect(QByteArray(handshakeOkNoAuth, -1 + sizeof handshakeOkNoAuth)) + << Chat::send(QByteArray(connect1, -1 + sizeof connect1)) + << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::expect("\1") // IPv4 address following + << Chat::skipBytes(6) // the server's local address and port + << ftpChat() + + // hostname connection + << Chat::Reconnect + << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) + << Chat::expect(QByteArray(handshakeOkNoAuth, -1 + sizeof handshakeOkNoAuth)) + << Chat::send(QByteArray(connect2, -1 + sizeof connect2)) + << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::expect("\1") // IPv4 address following + << Chat::skipBytes(6) // the server's local address and port + << ftpChat() + ); +} + +void tst_NetworkSelfTest::socks5ProxyAuth() +{ + netChat(1081, QList() + // unauthenticated connect -- will get error + << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) + << Chat::expect(QByteArray(handshakeAuthNotOk, -1 + sizeof handshakeAuthNotOk)) + << Chat::RemoteDisconnect + + // now try to connect with authentication + << Chat::Reconnect + << Chat::send(QByteArray(handshakeAuthPassword, -1 + sizeof handshakeAuthPassword)) + << Chat::expect(QByteArray(handshakeOkPasswdAuth, -1 + sizeof handshakeOkPasswdAuth)) + << Chat::send(QByteArray(connect1, -1 + sizeof connect1)) + << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::expect("\1") // IPv4 address following + << Chat::skipBytes(6) // the server's local address and port + << ftpChat() + ); +} + +QTEST_MAIN(tst_NetworkSelfTest) +#include "tst_networkselftest.moc" diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 60e6657..1cdb840 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -4,7 +4,8 @@ TEMPLATE = subdirs !wince*:SUBDIRS += \ headers -SUBDIRS += bic \ +SUBDIRS += _networkselftest \ + bic \ collections \ compile \ compilerwarnings \ -- cgit v0.12 From 87911c6c97b11bd7d10a38698460174b6cadfbe8 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 20 May 2009 09:50:47 +0200 Subject: Fix a leak because of an old legacy of QPixmapCache string API We have to replace the pixmap in the cache if it was previously there, we don't need to insert a new pixmap if a full update has been triggered. Reviewed-by:mbm --- src/gui/graphicsview/qgraphicsscene.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 1fbda85..126ea5b 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4759,10 +4759,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte } // Find pixmap in cache. - if (!itemCache->allExposed) - pixmapFound = QPixmapCache::find(pixmapKey, &pix); - else - pixmapFound = false; + pixmapFound = QPixmapCache::find(pixmapKey, &pix); // Render using item coordinate cache mode. if (cacheMode == QGraphicsItem::ItemCoordinateCache) { -- cgit v0.12 From 2a8d3ae2a4cf0eeaf007ad9a8fd9543aed9da3da Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 12:08:30 +0200 Subject: add more tests --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 188 ++++++++++++++++--------- 1 file changed, 124 insertions(+), 64 deletions(-) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 05c45ca..40c01bd 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -931,6 +931,7 @@ void tst_QStateMachine::customErrorStateNotInGraph() void tst_QStateMachine::restoreProperties() { QStateMachine machine; + QCOMPARE(machine.globalRestorePolicy(), QStateMachine::DoNotRestoreProperties); machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); QObject *object = new QObject(&machine); @@ -1094,6 +1095,12 @@ void tst_QStateMachine::stateEntryAndExit() QVERIFY(trans != 0); QCOMPARE(trans->sourceState(), (QAbstractState*)s2); QCOMPARE(trans->targetState(), (QAbstractState*)s3); + { + char warning[256]; + sprintf(warning, "QState::removeTransition: transition %p's source state (%p) is different from this state (%p)", trans, s2, s1); + QTest::ignoreMessage(QtWarningMsg, warning); + s1->removeTransition(trans); + } s2->removeTransition(trans); QCOMPARE(trans->sourceState(), (QAbstractState*)0); QCOMPARE(trans->targetState(), (QAbstractState*)s3); @@ -1106,6 +1113,13 @@ void tst_QStateMachine::stateEntryAndExit() QSignalSpy finishedSpy(&machine, SIGNAL(finished())); machine.setInitialState(s1); QCOMPARE(machine.initialState(), (QAbstractState*)s1); + { + char warning[256]; + sprintf(warning, "QState::setInitialState: state %p is not a child of this state (%p)", machine.rootState(), machine.rootState()); + QTest::ignoreMessage(QtWarningMsg, warning); + machine.setInitialState(machine.rootState()); + QCOMPARE(machine.initialState(), (QAbstractState*)s1); + } QVERIFY(machine.configuration().isEmpty()); globalTick = 0; QVERIFY(!machine.isRunning()); @@ -1238,6 +1252,11 @@ void tst_QStateMachine::assignPropertyWithAnimation() // Single animation { QStateMachine machine; + QVERIFY(machine.animationsEnabled()); + machine.setAnimationsEnabled(false); + QVERIFY(!machine.animationsEnabled()); + machine.setAnimationsEnabled(true); + QVERIFY(machine.animationsEnabled()); QObject obj; obj.setProperty("foo", 321); obj.setProperty("bar", 654); @@ -1338,6 +1357,10 @@ void tst_QStateMachine::assignPropertyWithAnimation() obj.setProperty("bar", 654); QState *s1 = new QState(machine.rootState()); QCOMPARE(s1->childMode(), QState::ExclusiveStates); + s1->setChildMode(QState::ParallelStates); + QCOMPARE(s1->childMode(), QState::ParallelStates); + s1->setChildMode(QState::ExclusiveStates); + QCOMPARE(s1->childMode(), QState::ExclusiveStates); QCOMPARE(s1->initialState(), (QAbstractState*)0); s1->setObjectName("s1"); s1->assignProperty(&obj, "foo", 123); @@ -1411,47 +1434,59 @@ class StringEventPoster : public QState { public: StringEventPoster(QStateMachine *machine, const QString &value, QState *parent = 0) - : QState(parent), m_machine(machine), m_value(value) {} + : QState(parent), m_machine(machine), m_value(value), m_delay(0) {} void setString(const QString &value) { m_value = value; } + void setDelay(int delay) + { m_delay = delay; } protected: virtual void onEntry(QEvent *) { - m_machine->postEvent(new StringEvent(m_value)); + m_machine->postEvent(new StringEvent(m_value), m_delay); } virtual void onExit(QEvent *) {} private: QStateMachine *m_machine; QString m_value; + int m_delay; }; void tst_QStateMachine::postEvent() { - QStateMachine machine; - StringEventPoster *s1 = new StringEventPoster(&machine, "a"); - QFinalState *s2 = new QFinalState; - s1->addTransition(new StringTransition("a", s2)); - machine.addState(s1); - machine.addState(s2); - machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s2)); + for (int x = 0; x < 2; ++x) { + QStateMachine machine; + { + QEvent e(QEvent::None); + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::postEvent: cannot post event when the state machine is not running"); + machine.postEvent(&e); + } + StringEventPoster *s1 = new StringEventPoster(&machine, "a"); + if (x == 1) + s1->setDelay(100); + QFinalState *s2 = new QFinalState; + s1->addTransition(new StringTransition("a", s2)); + machine.addState(s1); + machine.addState(s2); + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); - s1->setString("b"); - QFinalState *s3 = new QFinalState(); - machine.addState(s3); - s1->addTransition(new StringTransition("b", s3)); - finishedSpy.clear(); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s3)); + s1->setString("b"); + QFinalState *s3 = new QFinalState(); + machine.addState(s3); + s1->addTransition(new StringTransition("b", s3)); + finishedSpy.clear(); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s3)); + } } void tst_QStateMachine::stateFinished() @@ -1488,6 +1523,12 @@ void tst_QStateMachine::parallelStates() QFinalState *s1_2_f = new QFinalState(s1_2); s1_2_1->addTransition(s1_2_f); s1_2->setInitialState(s1_2_1); + { + char warning[256]; + sprintf(warning, "QState::setInitialState: ignoring attempt to set initial state of parallel state group %p", s1); + QTest::ignoreMessage(QtWarningMsg, warning); + s1->setInitialState(0); + } machine.addState(s1); QFinalState *s2 = new QFinalState(); @@ -1955,53 +1996,72 @@ void tst_QStateMachine::eventTransitions() void tst_QStateMachine::historyStates() { - QStateMachine machine; - QState *root = machine.rootState(); - QState *s0 = new QState(root); - QState *s00 = new QState(s0); - QState *s01 = new QState(s0); - QHistoryState *s0h = new QHistoryState(s0); - QState *s1 = new QState(root); - QFinalState *s2 = new QFinalState(root); - - s00->addTransition(new StringTransition("a", s01)); - s0->addTransition(new StringTransition("b", s1)); - s1->addTransition(new StringTransition("c", s0h)); - s0->addTransition(new StringTransition("d", s2)); - - root->setInitialState(s0); - s0->setInitialState(s00); + for (int x = 0; x < 2; ++x) { + QStateMachine machine; + QState *root = machine.rootState(); + QState *s0 = new QState(root); + QState *s00 = new QState(s0); + QState *s01 = new QState(s0); + QHistoryState *s0h; + if (x == 0) { + s0h = new QHistoryState(s0); + QCOMPARE(s0h->historyType(), QHistoryState::ShallowHistory); + s0h->setHistoryType(QHistoryState::DeepHistory); + } else { + s0h = new QHistoryState(QHistoryState::DeepHistory, s0); + } + QCOMPARE(s0h->historyType(), QHistoryState::DeepHistory); + s0h->setHistoryType(QHistoryState::ShallowHistory); + QCOMPARE(s0h->historyType(), QHistoryState::ShallowHistory); + QCOMPARE(s0h->defaultState(), (QAbstractState*)0); + s0h->setDefaultState(s00); + QCOMPARE(s0h->defaultState(), (QAbstractState*)s00); + char warning[256]; + sprintf(warning, "QHistoryState::setDefaultState: state %p does not belong to this history state's group (%p)", s0, s0); + QTest::ignoreMessage(QtWarningMsg, warning); + s0h->setDefaultState(s0); + QState *s1 = new QState(root); + QFinalState *s2 = new QFinalState(root); + + s00->addTransition(new StringTransition("a", s01)); + s0->addTransition(new StringTransition("b", s1)); + s1->addTransition(new StringTransition("c", s0h)); + s0->addTransition(new StringTransition("d", s2)); + + root->setInitialState(s0); + s0->setInitialState(s00); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s0)); - QVERIFY(machine.configuration().contains(s00)); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s0)); + QVERIFY(machine.configuration().contains(s00)); - machine.postEvent(new StringEvent("a")); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s0)); - QVERIFY(machine.configuration().contains(s01)); + machine.postEvent(new StringEvent("a")); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s0)); + QVERIFY(machine.configuration().contains(s01)); - machine.postEvent(new StringEvent("b")); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); + machine.postEvent(new StringEvent("b")); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); - machine.postEvent(new StringEvent("c")); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s0)); - QVERIFY(machine.configuration().contains(s01)); + machine.postEvent(new StringEvent("c")); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s0)); + QVERIFY(machine.configuration().contains(s01)); - machine.postEvent(new StringEvent("d")); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s2)); + machine.postEvent(new StringEvent("d")); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); - QTRY_COMPARE(finishedSpy.count(), 1); + QTRY_COMPARE(finishedSpy.count(), 1); + } } void tst_QStateMachine::startAndStop() -- cgit v0.12 From 42fe40e777a35818dcb9f7cd00ddf93e44477e36 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 22 May 2009 12:17:59 +0200 Subject: Revert "update the padnavigator example and suppress the padnavigator-ng" This reverts commit 1cad8c56002a61a6240e6580cdbd784209821fa6. Conflicts: examples/graphicsview/padnavigator/roundrectitem.cpp --- .../padnavigator/images/artsfftscope.png | Bin 1290 -> 1291 bytes examples/graphicsview/padnavigator/main.cpp | 4 + examples/graphicsview/padnavigator/panel.cpp | 168 ++++++++++----------- examples/graphicsview/padnavigator/panel.h | 29 ++-- .../graphicsview/padnavigator/roundrectitem.cpp | 109 ++++++++----- examples/graphicsview/padnavigator/roundrectitem.h | 16 +- examples/graphicsview/padnavigator/splashitem.cpp | 25 +-- examples/graphicsview/padnavigator/splashitem.h | 6 + 8 files changed, 207 insertions(+), 150 deletions(-) diff --git a/examples/graphicsview/padnavigator/images/artsfftscope.png b/examples/graphicsview/padnavigator/images/artsfftscope.png index 756a1cf..4db003f 100644 Binary files a/examples/graphicsview/padnavigator/images/artsfftscope.png and b/examples/graphicsview/padnavigator/images/artsfftscope.png differ diff --git a/examples/graphicsview/padnavigator/main.cpp b/examples/graphicsview/padnavigator/main.cpp index f7d6f90..dc5ff0c 100644 --- a/examples/graphicsview/padnavigator/main.cpp +++ b/examples/graphicsview/padnavigator/main.cpp @@ -40,6 +40,10 @@ ****************************************************************************/ #include +#ifndef QT_NO_OPENGL +# include +#endif + #include "panel.h" int main(int argc, char *argv[]) diff --git a/examples/graphicsview/padnavigator/panel.cpp b/examples/graphicsview/padnavigator/panel.cpp index c088fbc..28a3cb4 100644 --- a/examples/graphicsview/padnavigator/panel.cpp +++ b/examples/graphicsview/padnavigator/panel.cpp @@ -50,15 +50,15 @@ #endif #include +#include + Panel::Panel(int width, int height) - : selectedIndex(0), - grid(width*height), + : selectedX(0), + selectedY(0), width(width), height(height), flipped(false), - flippingGroup(0), - rotationXanim(0), - rotationYanim(0) + flipLeft(true) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -72,9 +72,12 @@ Panel::Panel(int width, int height) #endif setMinimumSize(50, 50); + selectionTimeLine = new QTimeLine(150, this); + flipTimeLine = new QTimeLine(500, this); + QRectF bounds((-width / 2.0) * 150, (-height / 2.0) * 150, width * 150, height * 150); - QGraphicsScene *scene = new QGraphicsScene(bounds, this); + scene = new QGraphicsScene(bounds, this); scene->setItemIndexMethod(QGraphicsScene::NoIndex); setScene(scene); @@ -87,24 +90,28 @@ Panel::Panel(int width, int height) ui->hostName->setFocus(); backItem = new RoundRectItem(bounds, embed->palette().window(), embed); - backItem->setYRotation(180); + backItem->setTransform(QTransform().rotate(180, Qt::YAxis)); backItem->setParentItem(baseItem); selectionItem = new RoundRectItem(QRectF(-60, -60, 120, 120), Qt::gray); selectionItem->setParentItem(baseItem); selectionItem->setZValue(-1); - selectionItem->setPos(posForLocation(0)); + selectionItem->setPos(posForLocation(0, 0)); + startPos = selectionItem->pos(); - int currentIndex = 0; + grid = new QGraphicsItem **[height]; + for (int y = 0; y < height; ++y) { + grid[y] = new QGraphicsItem *[width]; + for (int x = 0; x < width; ++x) { RoundRectItem *item = new RoundRectItem(QRectF(-54, -54, 108, 108), QColor(214, 240, 110, 128)); - item->setPos(posForLocation(currentIndex)); + item->setPos(posForLocation(x, y)); item->setParentItem(baseItem); item->setFlag(QGraphicsItem::ItemIsFocusable); - grid[currentIndex++] = item; + grid[y][x] = item; switch (qrand() % 9) { case 0: item->setPixmap(QPixmap(":/images/kontact_contacts.png")); break; @@ -124,10 +131,14 @@ Panel::Panel(int width, int height) } } - grid.first()->setFocus(); + grid[0][0]->setFocus(); connect(backItem, SIGNAL(activated()), this, SLOT(flip())); + connect(selectionTimeLine, SIGNAL(valueChanged(qreal)), + this, SLOT(updateSelectionStep(qreal))); + connect(flipTimeLine, SIGNAL(valueChanged(qreal)), + this, SLOT(updateFlipStep(qreal))); splash = new SplashItem; splash->setZValue(5); @@ -136,15 +147,16 @@ Panel::Panel(int width, int height) splash->grabKeyboard(); - //initialize the position - baseItem->setYRotation(selectionItem->x()/6.); - baseItem->setXRotation(selectionItem->y()/6.); + updateSelectionStep(0); setWindowTitle(tr("Pad Navigator Example")); } Panel::~Panel() { + for (int y = 0; y < height; ++y) + delete [] grid[y]; + delete [] grid; } void Panel::keyPressEvent(QKeyEvent *event) @@ -154,93 +166,73 @@ void Panel::keyPressEvent(QKeyEvent *event) return; } - selectedIndex = (selectedIndex + grid.count() + (event->key() == Qt::Key_Right) - (event->key() == Qt::Key_Left) - + width * ((event->key() == Qt::Key_Down) - (event->key() == Qt::Key_Up))) % grid.count(); - grid[selectedIndex]->setFocus(); - - const QPointF pos = posForLocation(selectedIndex); - - const double angleY = pos.x() / 6., - angleX = pos.y() / 6.; - - QAnimationGroup *group = new QParallelAnimationGroup(); - - QVariantAnimation *anim = new QPropertyAnimation(baseItem, "xRotation"); - anim->setEndValue(angleX); - anim->setDuration(150); - anim->setEasingCurve(QEasingCurve::OutInSine); - group->addAnimation(anim); - - anim = new QPropertyAnimation(baseItem, "yRotation"); - anim->setEndValue(angleY); - anim->setDuration(150); - anim->setEasingCurve(QEasingCurve::OutInSine); - group->addAnimation(anim); - - anim = new QPropertyAnimation(selectionItem, "pos"); - anim->setEndValue(pos); - anim->setDuration(150); - anim->setEasingCurve(QEasingCurve::Linear); - group->addAnimation(anim); - - group->start(QAbstractAnimation::DeleteWhenStopped); + selectedX = (selectedX + width + (event->key() == Qt::Key_Right) - (event->key() == Qt::Key_Left)) % width; + selectedY = (selectedY + height + (event->key() == Qt::Key_Down) - (event->key() == Qt::Key_Up)) % height; + grid[selectedY][selectedX]->setFocus(); + + selectionTimeLine->stop(); + startPos = selectionItem->pos(); + endPos = posForLocation(selectedX, selectedY); + selectionTimeLine->start(); } void Panel::resizeEvent(QResizeEvent *event) { QGraphicsView::resizeEvent(event); - fitInView(scene()->sceneRect(), Qt::KeepAspectRatio); + fitInView(scene->sceneRect(), Qt::KeepAspectRatio); } -void Panel::flip() +void Panel::updateSelectionStep(qreal val) { - grid[selectedIndex]->setFocus(); - - if (flippingGroup == 0) { - flippingGroup = new QParallelAnimationGroup(this); - - const qreal zoomOut = qreal(.75); - - //slight scaling down while flipping - QVariantAnimation *anim = new QPropertyAnimation(baseItem, "yScale"); - anim->setKeyValueAt(qreal(.5), zoomOut); - anim->setEndValue(1); - anim->setEasingCurve(QEasingCurve::OutInSine); - anim->setDuration(500); - flippingGroup->addAnimation(anim); - - anim = new QPropertyAnimation(baseItem, "xScale"); - anim->setKeyValueAt(qreal(.5), zoomOut); - anim->setEndValue(1); - anim->setEasingCurve(QEasingCurve::OutInSine); - anim->setDuration(500); - flippingGroup->addAnimation(anim); - - rotationXanim = new QPropertyAnimation(baseItem, "xRotation"); - rotationXanim->setEndValue(0); - rotationXanim->setDuration(500); - flippingGroup->addAnimation(rotationXanim); - - rotationYanim = new QPropertyAnimation(baseItem, "yRotation"); - rotationYanim->setStartValue(0); - rotationYanim->setEndValue(180); - rotationYanim->setDuration(500); - flippingGroup->addAnimation(rotationYanim); - } + QPointF newPos(startPos.x() + (endPos - startPos).x() * val, + startPos.y() + (endPos - startPos).y() * val); + selectionItem->setPos(newPos); + + QTransform transform; + yrot = newPos.x() / 6.0; + xrot = newPos.y() / 6.0; + transform.rotate(newPos.x() / 6.0, Qt::YAxis); + transform.rotate(newPos.y() / 6.0, Qt::XAxis); + baseItem->setTransform(transform); +} - if (flippingGroup->currentTime() != 0 && flippingGroup->direction() == QAbstractAnimation::Forward) - flippingGroup->setDirection(QAbstractAnimation::Backward); +void Panel::updateFlipStep(qreal val) +{ + qreal finalxrot = xrot - xrot * val; + qreal finalyrot; + if (flipLeft) + finalyrot = yrot - yrot * val - 180 * val; else - flippingGroup->setDirection(QAbstractAnimation::Forward); + finalyrot = yrot - yrot * val + 180 * val; + QTransform transform; + transform.rotate(finalyrot, Qt::YAxis); + transform.rotate(finalxrot, Qt::XAxis); + qreal scale = 1 - sin(3.14 * val) * 0.3; + transform.scale(scale, scale); + baseItem->setTransform(transform); + if (val == 0) + grid[selectedY][selectedX]->setFocus(); +} - flippingGroup->start(); - flipped = !flipped; +void Panel::flip() +{ + if (flipTimeLine->state() == QTimeLine::Running) + return; + + if (flipTimeLine->currentValue() == 0) { + flipTimeLine->setDirection(QTimeLine::Forward); + flipTimeLine->start(); + flipped = true; + flipLeft = selectionItem->pos().x() < 0; + } else { + flipTimeLine->setDirection(QTimeLine::Backward); + flipTimeLine->start(); + flipped = false; + } } -QPointF Panel::posForLocation(int index) const +QPointF Panel::posForLocation(int x, int y) const { - const int x = index % width, - y = index / width; return QPointF(x * 150, y * 150) - QPointF((width - 1) * 75, (height - 1) * 75); } diff --git a/examples/graphicsview/padnavigator/panel.h b/examples/graphicsview/padnavigator/panel.h index cc03530..03876b7 100644 --- a/examples/graphicsview/padnavigator/panel.h +++ b/examples/graphicsview/padnavigator/panel.h @@ -40,12 +40,10 @@ ****************************************************************************/ #include -#include QT_BEGIN_NAMESPACE +class QTimeLine; class Ui_BackSide; -class QAnimationGroup; -class QPropertyAnimation; QT_END_NAMESPACE; class RoundRectItem; @@ -62,24 +60,33 @@ protected: void resizeEvent(QResizeEvent *event); private Q_SLOTS: + void updateSelectionStep(qreal val); + void updateFlipStep(qreal val); void flip(); private: - QPointF posForLocation(int index) const; + QPointF posForLocation(int x, int y) const; - QGraphicsWidget *selectionItem; - QGraphicsWidget *baseItem; + QGraphicsScene *scene; + RoundRectItem *selectionItem; + RoundRectItem *baseItem; RoundRectItem *backItem; QGraphicsWidget *splash; - int selectedIndex; + QTimeLine *selectionTimeLine; + QTimeLine *flipTimeLine; + int selectedX, selectedY; - QVector grid; + QGraphicsItem ***grid; + QPointF startPos; + QPointF endPos; + qreal xrot, yrot; + qreal xrot2, yrot2; + int width; int height; bool flipped; - Ui_BackSide *ui; + bool flipLeft; - QAnimationGroup *flippingGroup; - QPropertyAnimation *rotationXanim, *rotationYanim; + Ui_BackSide *ui; }; diff --git a/examples/graphicsview/padnavigator/roundrectitem.cpp b/examples/graphicsview/padnavigator/roundrectitem.cpp index 73d6d33..c5dc35d 100644 --- a/examples/graphicsview/padnavigator/roundrectitem.cpp +++ b/examples/graphicsview/padnavigator/roundrectitem.cpp @@ -44,61 +44,72 @@ #include RoundRectItem::RoundRectItem(const QRectF &rect, const QBrush &brush, QWidget *embeddedWidget) - : QGraphicsWidget(), - m_rect(rect), + : QGraphicsRectItem(rect), brush(brush), + timeLine(75), + lastVal(0), + opa(1), proxyWidget(0) { + connect(&timeLine, SIGNAL(valueChanged(qreal)), + this, SLOT(updateValue(qreal))); + if (embeddedWidget) { proxyWidget = new QGraphicsProxyWidget(this); proxyWidget->setFocusPolicy(Qt::StrongFocus); proxyWidget->setWidget(embeddedWidget); + proxyWidget->setGeometry(boundingRect().adjusted(25, 25, -25, -25)); } } void RoundRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { - const bool widgetHidden = parentItem() == 0 || qAbs(static_cast(parentItem())->yRotation()) < 90; - - if (proxyWidget) { - if (widgetHidden) { + QTransform x = painter->worldTransform(); + + QLineF unit = x.map(QLineF(0, 0, 1, 1)); + if (unit.p1().x() > unit.p2().x() || unit.p1().y() > unit.p2().y()) { + if (proxyWidget && proxyWidget->isVisible()) { proxyWidget->hide(); - } else { - if (!proxyWidget->isVisible()) { - proxyWidget->setGeometry(boundingRect().adjusted(25, 25, -25, -25)); - proxyWidget->show(); - proxyWidget->setFocus(); - } - painter->setBrush(brush); - painter->setPen(QPen(Qt::black, 1)); - painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - painter->drawRoundRect(m_rect); + proxyWidget->setGeometry(rect()); } - } else if (widgetHidden) { - painter->setPen(Qt::NoPen); - painter->setBrush(QColor(0, 0, 0, 64)); - painter->drawRoundRect(m_rect.translated(2, 2)); + return; + } - QLinearGradient gradient(m_rect.topLeft(), m_rect.bottomRight()); + if (proxyWidget && !proxyWidget->isVisible()) { + proxyWidget->show(); + proxyWidget->setFocus(); + } + if (proxyWidget && proxyWidget->pos() != QPoint()) + proxyWidget->setGeometry(boundingRect().adjusted(25, 25, -25, -25)); + + painter->setOpacity(opacity()); + painter->setPen(Qt::NoPen); + painter->setBrush(QColor(0, 0, 0, 64)); + painter->drawRoundRect(rect().translated(2, 2)); + + if (!proxyWidget) { + QLinearGradient gradient(rect().topLeft(), rect().bottomRight()); const QColor col = brush.color(); gradient.setColorAt(0, col); - gradient.setColorAt(1, col.dark(200)); + gradient.setColorAt(1, col.dark(int(200 + lastVal * 50))); painter->setBrush(gradient); - painter->setPen(QPen(Qt::black, 1)); - painter->drawRoundRect(m_rect); - if (!pix.isNull()) { - painter->scale(qreal(1.95), qreal(1.95)); - painter->drawPixmap(-pix.width() / 2, -pix.height() / 2, pix); - } + } else { + painter->setBrush(brush); } + painter->setPen(QPen(Qt::black, 1)); + painter->drawRoundRect(rect()); + if (!pix.isNull()) { + painter->scale(1.95, 1.95); + painter->drawPixmap(-pix.width() / 2, -pix.height() / 2, pix);; + } } QRectF RoundRectItem::boundingRect() const { - qreal penW = qreal(.5); - qreal shadowW = 2; - return m_rect.adjusted(-penW, -penW, penW + shadowW, penW + shadowW); + qreal penW = 0.5; + qreal shadowW = 2.0; + return rect().adjusted(-penW, -penW, penW + shadowW, penW + shadowW); } void RoundRectItem::setPixmap(const QPixmap &pixmap) @@ -108,26 +119,46 @@ void RoundRectItem::setPixmap(const QPixmap &pixmap) update(); } +qreal RoundRectItem::opacity() const +{ + RoundRectItem *parent = parentItem() ? (RoundRectItem *)parentItem() : 0; + return opa + (parent ? parent->opacity() : 0); +} + +void RoundRectItem::setOpacity(qreal opacity) +{ + opa = opacity; + update(); +} + void RoundRectItem::keyPressEvent(QKeyEvent *event) { - if (event->isAutoRepeat() || event->key() != Qt::Key_Return) { - QGraphicsWidget::keyPressEvent(event); + if (event->isAutoRepeat() || event->key() != Qt::Key_Return + || (timeLine.state() == QTimeLine::Running && timeLine.direction() == QTimeLine::Forward)) { + QGraphicsRectItem::keyPressEvent(event); return; } - if (!proxyWidget) - setScale(qreal(.9), qreal(.9)); - + timeLine.stop(); + timeLine.setDirection(QTimeLine::Forward); + timeLine.start(); emit activated(); } void RoundRectItem::keyReleaseEvent(QKeyEvent *event) { - if (event->isAutoRepeat() || event->key() != Qt::Key_Return) { - QGraphicsWidget::keyReleaseEvent(event); + if (event->key() != Qt::Key_Return) { + QGraphicsRectItem::keyReleaseEvent(event); return; } + timeLine.stop(); + timeLine.setDirection(QTimeLine::Backward); + timeLine.start(); +} +void RoundRectItem::updateValue(qreal value) +{ + lastVal = value; if (!proxyWidget) - setScale(1, 1); + setTransform(QTransform().scale(1 - value / 10.0, 1 - value / 10.0)); } diff --git a/examples/graphicsview/padnavigator/roundrectitem.h b/examples/graphicsview/padnavigator/roundrectitem.h index b0d44dd..33e33d7 100644 --- a/examples/graphicsview/padnavigator/roundrectitem.h +++ b/examples/graphicsview/padnavigator/roundrectitem.h @@ -40,14 +40,15 @@ ****************************************************************************/ #include +#include +#include #include -#include QT_BEGIN_NAMESPACE class QGraphicsProxyWidget; QT_END_NAMESPACE; -class RoundRectItem : public QGraphicsWidget +class RoundRectItem : public QObject, public QGraphicsRectItem { Q_OBJECT public: @@ -58,6 +59,9 @@ public: void setPixmap(const QPixmap &pixmap); + qreal opacity() const; + void setOpacity(qreal opacity); + Q_SIGNALS: void activated(); @@ -65,9 +69,15 @@ protected: void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); +private slots: + void updateValue(qreal value); + private: - QRectF m_rect; QBrush brush; QPixmap pix; + QTimeLine timeLine; + qreal lastVal; + qreal opa; + QGraphicsProxyWidget *proxyWidget; }; diff --git a/examples/graphicsview/padnavigator/splashitem.cpp b/examples/graphicsview/padnavigator/splashitem.cpp index a83d4d5..2a374bf 100644 --- a/examples/graphicsview/padnavigator/splashitem.cpp +++ b/examples/graphicsview/padnavigator/splashitem.cpp @@ -46,6 +46,12 @@ SplashItem::SplashItem(QGraphicsItem *parent) : QGraphicsWidget(parent) { + opacity = 1.0; + + + timeLine = new QTimeLine(350); + timeLine->setCurveShape(QTimeLine::EaseInCurve); + connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(setValue(qreal))); text = tr("Welcome to the Pad Navigator Example. You can use the" " keyboard arrows to navigate the icons, and press enter" @@ -55,6 +61,7 @@ SplashItem::SplashItem(QGraphicsItem *parent) void SplashItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { + painter->setOpacity(opacity); painter->setPen(QPen(Qt::black, 2)); painter->setBrush(QColor(245, 245, 255, 220)); painter->setClipRect(rect()); @@ -72,14 +79,14 @@ void SplashItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWid void SplashItem::keyPressEvent(QKeyEvent * /* event */) { - QVariantAnimation *anim = new QPropertyAnimation(this, "pos"); - anim->setEndValue(QPointF(x(), scene()->sceneRect().top() - rect().height())); - anim->setDuration(350); - anim->start(QAbstractAnimation::DeleteWhenStopped); - - anim = new QPropertyAnimation(this, "opacity"); - anim->setEndValue(0); - anim->start(QAbstractAnimation::DeleteWhenStopped); + if (timeLine->state() == QTimeLine::NotRunning) + timeLine->start(); +} - connect(anim, SIGNAL(finished()), SLOT(close())); +void SplashItem::setValue(qreal value) +{ + opacity = 1 - value; + setPos(x(), scene()->sceneRect().top() - rect().height() * value); + if (value == 1) + hide(); } diff --git a/examples/graphicsview/padnavigator/splashitem.h b/examples/graphicsview/padnavigator/splashitem.h index e2655ec..982bbe2 100644 --- a/examples/graphicsview/padnavigator/splashitem.h +++ b/examples/graphicsview/padnavigator/splashitem.h @@ -40,6 +40,7 @@ ****************************************************************************/ #include +#include #include class SplashItem : public QGraphicsWidget @@ -52,6 +53,11 @@ public: protected: void keyPressEvent(QKeyEvent *event); +private Q_SLOTS: + void setValue(qreal value); + private: + QTimeLine *timeLine; QString text; + qreal opacity; }; -- cgit v0.12 From 0babd12eb7e982f47b379fe70f011daffbb8c6e8 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Fri, 22 May 2009 12:57:57 +0200 Subject: Updated WebKit from /home/ariya/dev/webkit/qtwebkit-4.5 to origin/qtwebkit-4.5 ( 4ee8af9348b3f57d3c0f3575ae0a58336cf07a92 ) Changes in WebKit since the last update: ++ b/LayoutTests/ChangeLog 2009-05-20 Holger Hans Peter Freyther Reviewed by Anders Carlsson. https://bugs.webkit.org/show_bug.cgi?id=24510 Add a test case that Netscape Plugin can properly determine if a given object has a specific method and property. The test will ask the plugin to call hasproperty and hasmethod and will compare the result with what is expected. This approach is taken from netscape-get-property-return-value.html * plugins/netscape-invoke-browserfuncs-expected.txt: Added. * plugins/netscape-invoke-browserfuncs.html: Added. ++ b/WebCore/ChangeLog 2009-05-19 Kenneth Rohde Christiansen Reviewed by Simon Hausmann. Do not call the parent implementation (Widget::) in show() and hide() of the PluginViewQt, as it always changes the visible state of the platformWidget (equal to the platformPluginWidget in the Qt port), thus ignoring the isParentVisible() test. * plugins/qt/PluginViewQt.cpp: (WebCore::PluginView::show): (WebCore::PluginView::hide): 2009-04-22 Tamas Szirbucz Reviewed by Ariya Hidayat. https://bugs.webkit.org/show_bug.cgi?id=25023 Delete reply in QNetworkReplyHandler::abort() to avoid leak. * platform/network/qt/QNetworkReplyHandler.cpp: (WebCore::QNetworkReplyHandler::abort): 2009-05-20 Holger Hans Peter Freyther Reviewed by Anders Carlsson. https://bugs.webkit.org/show_bug.cgi?id=24510 Fix a bug where the browserfuncs were not properly assigned, make hasproperty use _NP_HasProperty and hasmethod _NP_HasMethod. Test: plugins/netscape-invoke-browserfuncs.html * plugins/gtk/PluginPackageGtk.cpp: (WebCore::PluginPackage::load): Fix assignment * plugins/qt/PluginPackageQt.cpp: (WebCore::PluginPackage::load): Fix assignment ++ b/WebKit/qt/ChangeLog 2009-05-19 Kenneth Rohde Christiansen Reviewed by Simon Hausmann. Fix a plugin bug in the WebKit code, similar to the one in WebCore. The problem is when a non visible QtPluginWidget would show it self in a sibling frame. The problem was due to our clipping. In Qt, if setMask is set with an empty QRegion, no clipping will be performed, so in that case we hide the PluginContainer * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::): ++ b/WebKitTools/ChangeLog 2009-05-14 Holger Hans Peter Freyther Reviewed by Anders Carlsson. https://bugs.webkit.org/show_bug.cgi?id=24510 where Add testHasProperty and testHasMethod to the existing functions of the PluginObject to be able to test the browser hasproperty and hasmethod implementation. Invoke them from pluginInvoke. Change the defines to an enum to avoid manually updating NUM_METHOD_IDENTIFIERS and assigning numbers. * DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp: (testHasProperty): test hasproperty (testHasMethod): test hasmethod (pluginInvoke): invoke the two --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 39 ++++++++++++++++++++++ .../platform/network/qt/QNetworkReplyHandler.cpp | 1 + .../webkit/WebCore/plugins/qt/PluginPackageQt.cpp | 4 +-- .../webkit/WebCore/plugins/qt/PluginViewQt.cpp | 8 +++-- src/3rdparty/webkit/WebKit/qt/ChangeLog | 14 ++++++++ .../qt/WebCoreSupport/FrameLoaderClientQt.cpp | 8 ++++- 7 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 7adbd6f..7d5d1c5 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - 40b523e9eaaba38c182e5a9c319f0069ebf98330 + 4ee8af9348b3f57d3c0f3575ae0a58336cf07a92 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index a4cb62d..072beee 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,42 @@ +2009-05-19 Kenneth Rohde Christiansen + + Reviewed by Simon Hausmann. + + Do not call the parent implementation (Widget::) in show() and hide() + of the PluginViewQt, as it always changes the visible state of the + platformWidget (equal to the platformPluginWidget in the Qt port), + thus ignoring the isParentVisible() test. + + * plugins/qt/PluginViewQt.cpp: + (WebCore::PluginView::show): + (WebCore::PluginView::hide): + +2009-04-22 Tamas Szirbucz + + Reviewed by Ariya Hidayat. + + https://bugs.webkit.org/show_bug.cgi?id=25023 + Delete reply in QNetworkReplyHandler::abort() to avoid leak. + + * platform/network/qt/QNetworkReplyHandler.cpp: + (WebCore::QNetworkReplyHandler::abort): + +2009-05-20 Holger Hans Peter Freyther + + Reviewed by Anders Carlsson. + + https://bugs.webkit.org/show_bug.cgi?id=24510 + + Fix a bug where the browserfuncs were not properly assigned, + make hasproperty use _NP_HasProperty and hasmethod _NP_HasMethod. + + Test: plugins/netscape-invoke-browserfuncs.html + + * plugins/gtk/PluginPackageGtk.cpp: + (WebCore::PluginPackage::load): Fix assignment + * plugins/qt/PluginPackageQt.cpp: + (WebCore::PluginPackage::load): Fix assignment + 2009-05-11 Yael Aharon Reviewed by Holger Freyther. diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 2c730a6..3e9b239 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -174,6 +174,7 @@ void QNetworkReplyHandler::abort() if (m_reply) { QNetworkReply* reply = release(); reply->abort(); + reply->deleteLater(); deleteLater(); } } diff --git a/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp b/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp index 4387813..13f5394 100644 --- a/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp @@ -151,8 +151,8 @@ bool PluginPackage::load() m_browserFuncs.getproperty = _NPN_GetProperty; m_browserFuncs.setproperty = _NPN_SetProperty; m_browserFuncs.removeproperty = _NPN_RemoveProperty; - m_browserFuncs.hasproperty = _NPN_HasMethod; - m_browserFuncs.hasmethod = _NPN_HasProperty; + m_browserFuncs.hasproperty = _NPN_HasProperty; + m_browserFuncs.hasmethod = _NPN_HasMethod; m_browserFuncs.setexception = _NPN_SetException; m_browserFuncs.enumerate = _NPN_Enumerate; m_browserFuncs.construct = _NPN_Construct; diff --git a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp index 43c772f..e856f92 100644 --- a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp @@ -113,7 +113,9 @@ void PluginView::show() if (isParentVisible() && platformPluginWidget()) platformPluginWidget()->setVisible(true); - Widget::show(); + // do not call parent impl. here as it will set the platformWidget + // (same as platformPluginWidget in the Qt port) to visible, even + // when parent isn't visible. } void PluginView::hide() @@ -123,7 +125,9 @@ void PluginView::hide() if (isParentVisible() && platformPluginWidget()) platformPluginWidget()->setVisible(false); - Widget::hide(); + // do not call parent impl. here as it will set the platformWidget + // (same as platformPluginWidget in the Qt port) to invisible, even + // when parent isn't visible. } void PluginView::paint(GraphicsContext* context, const IntRect& rect) diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index 2aeb8da..d9f925a 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,17 @@ +2009-05-19 Kenneth Rohde Christiansen + + Reviewed by Simon Hausmann. + + Fix a plugin bug in the WebKit code, similar to the one in WebCore. + + The problem is when a non visible QtPluginWidget would show it self + in a sibling frame. The problem was due to our clipping. In Qt, + if setMask is set with an empty QRegion, no clipping will + be performed, so in that case we hide the PluginContainer + + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::): + 2009-03-27 Erik L. Bunce Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp index c421d42..a2b33c0 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp @@ -1058,7 +1058,13 @@ public: IntRect clipRect(static_cast(parentScrollView)->windowClipRect()); clipRect.move(-windowRect.x(), -windowRect.y()); clipRect.intersect(platformWidget()->rect()); - platformWidget()->setMask(QRegion(clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height())); + + QRegion clipRegion = QRegion(clipRect); + platformWidget()->setMask(clipRegion); + + // if setMask is set with an empty QRegion, no clipping will + // be performed, so in that case we hide the platformWidget + platformWidget()->setVisible(!clipRegion.isEmpty()); } }; -- cgit v0.12 From ec8c6b9f5a25f9d4c437fbb13f073aeebc09cb3f Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Fri, 22 May 2009 13:09:17 +0200 Subject: Updates QtWebKit sections in changes-4.5.2 after commit 0babd12e. --- dist/changes-4.5.2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/changes-4.5.2 b/dist/changes-4.5.2 index b3e808f..1e00208 100644 --- a/dist/changes-4.5.2 +++ b/dist/changes-4.5.2 @@ -42,8 +42,8 @@ Third party components Memory (r41527, r43764, r43828, r43830) JavaScript (r39882, r40086, r40131, r40133) Rendering (r41285, r41296, r41659, r42887) - Network (r41664, r42516) - Plugins (r41346, r43550) + Network (r41664, r42516, r42747) + Plugins (r41346, r43550, r43915, r43917, r43923) Clipboard (r41360) **************************************************************************** -- cgit v0.12 From 5a734e4657161e0877b32181df35a56241b21de4 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 22 May 2009 13:24:44 +0200 Subject: Fix the way the transform and the properties are marked as dirty in QGraphicsItem Acknowledged-by: Thierry --- src/gui/graphicsview/qgraphicsitem.cpp | 9 +++-- src/gui/graphicsview/qgraphicsitem_p.h | 2 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 50 ++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b7e88f4..828dd4f 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2607,7 +2607,6 @@ QTransform QGraphicsItem::transform() const QVariant v(x); d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, v); d_ptr->dirtyTransform = 0; - d_ptr->dirtyTransformComponents = 1; const_cast(this)->itemChange(ItemTransformHasChanged, v); return x; } @@ -3200,9 +3199,9 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) prepareGeometryChange(); d_ptr->hasTransform = !newTransform.isIdentity(); d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform); + d_ptr->dirtyTransformComponents = 1; + d_ptr->dirtyTransform = 0; d_ptr->invalidateSceneTransformCache(); - if (d_ptr->hasDecomposedTransform) - d_ptr->dirtyTransform = 1; // Send post-notification. // NB! We have to change the value from QMatrix to QTransform. @@ -3253,9 +3252,9 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine) prepareGeometryChange(); d_ptr->hasTransform = !newTransform.isIdentity(); d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform); + d_ptr->dirtyTransformComponents = 1; + d_ptr->dirtyTransform = 0; d_ptr->invalidateSceneTransformCache(); - if (d_ptr->hasDecomposedTransform) - d_ptr->dirtyTransform = 1; // Send post-notification. itemChange(ItemTransformHasChanged, newTransformVariant); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index cebc8ca..b2569c1 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -346,7 +346,7 @@ public: int globalStackingOrder; int sceneTransformIndex; - struct DecomposedTransform; + struct DecomposedTransform; DecomposedTransform *decomposedTransform() const { QGraphicsItemPrivate *that = const_cast(this); diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index d41b3b4..c03c420 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -6404,26 +6404,26 @@ void tst_QGraphicsItem::setTransformProperties_data() QTest::addColumn("shearY"); QTest::newRow("nothing") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) - << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0); QTest::newRow("rotationZ") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(42.2) - << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0); QTest::newRow("rotationXY") << QPointF() << qreal(12.5) << qreal(53.6) << qreal(0.0) - << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0); QTest::newRow("rotationXYZ") << QPointF() << qreal(-25) << qreal(12) << qreal(556) - << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0); QTest::newRow("rotationXYZ dicentred") << QPointF(-53, 25.2) << qreal(-2578.2) << qreal(4565.2) << qreal(56) - << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0); + << qreal(1) << qreal(1) << qreal(0.0) << qreal(0.0); QTest::newRow("Scale") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(6) << qreal(0.5) << qreal(0.0) << qreal(0.0); QTest::newRow("Shear") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) - << qreal(0.0) << qreal(0.0) << qreal(2.2) << qreal(0.5); + << qreal(1) << qreal(1) << qreal(2.2) << qreal(0.5); QTest::newRow("Scale and Shear") << QPointF() << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(5.2) << qreal(2.1) << qreal(5.2) << qreal(5.5); @@ -6475,6 +6475,44 @@ void tst_QGraphicsItem::setTransformProperties() QCOMPARE(item->transformOrigin(), origin); QCOMPARE(result, item->transform()); + + //----------------------------------------------------------------- + //Change the rotation Z + item->setZRotation(45); + QTransform result2; + result2.translate(origin.x(), origin.y()); + result2.rotate(rotationX, Qt::XAxis); + result2.rotate(rotationY, Qt::YAxis); + result2.rotate(45, Qt::ZAxis); + result2.shear(shearX, shearY); + result2.scale(scaleX, scaleY); + result2.translate(-origin.x(), -origin.y()); + + QCOMPARE(item->xRotation(), rotationX); + QCOMPARE(item->yRotation(), rotationY); + QCOMPARE(item->zRotation(), 45.0); + QCOMPARE(item->xScale(), scaleX); + QCOMPARE(item->yScale(), scaleY); + QCOMPARE(item->horizontalShear(), shearX); + QCOMPARE(item->verticalShear(), shearY); + QCOMPARE(item->transformOrigin(), origin); + + QCOMPARE(result2, item->transform()); + + //----------------------------------------------------------------- + // calling setTransform() should reset the properties to their default + item->setTransform(result); + + QCOMPARE(item->xRotation(), 0.0); + QCOMPARE(item->yRotation(), 0.0); + QCOMPARE(item->zRotation(), 0.0); + QCOMPARE(item->xScale(), 1.0); + QCOMPARE(item->yScale(), 1.0); + QCOMPARE(item->horizontalShear(), 0.0); + QCOMPARE(item->verticalShear(), 0.0); + QCOMPARE(item->transformOrigin(), QPointF(0,0)); + + QCOMPARE(result, item->transform()); } -- cgit v0.12 From 1a709fbe25a2446a9b311ded88aec5565258f3ac Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 13:11:41 +0200 Subject: Say hello to animation API & state machine API --- demos/qtdemo/xml/examples.xml | 15 + doc/src/animation.qdoc | 368 ++ doc/src/diagrams/animations-architecture.svg | 351 ++ .../diagrams/programs/easingcurve/easingcurve.pro | 13 + doc/src/diagrams/programs/easingcurve/main.cpp | 90 + doc/src/examples-overview.qdoc | 8 + doc/src/examples.qdoc | 17 + doc/src/examples/eventtransitions.qdoc | 86 + doc/src/examples/factorial.qdoc | 102 + doc/src/examples/pingpong.qdoc | 107 + doc/src/examples/stickman.qdoc | 115 + doc/src/examples/tankgame.qdoc | 117 + doc/src/examples/trafficlight.qdoc | 99 + doc/src/examples/twowaybutton.qdoc | 82 + doc/src/external-resources.qdoc | 10 + doc/src/groups.qdoc | 23 + doc/src/images/animations-architecture.png | Bin 0 -> 27619 bytes doc/src/images/factorial-example.png | Bin 0 -> 4032 bytes doc/src/images/pingpong-example.png | Bin 0 -> 7843 bytes doc/src/images/qeasingcurve-cosinecurve.png | Bin 0 -> 2544 bytes doc/src/images/qeasingcurve-inback.png | Bin 0 -> 2225 bytes doc/src/images/qeasingcurve-inbounce.png | Bin 0 -> 2378 bytes doc/src/images/qeasingcurve-incirc.png | Bin 0 -> 2138 bytes doc/src/images/qeasingcurve-incubic.png | Bin 0 -> 2230 bytes doc/src/images/qeasingcurve-incurve.png | Bin 0 -> 2325 bytes doc/src/images/qeasingcurve-inelastic.png | Bin 0 -> 2314 bytes doc/src/images/qeasingcurve-inexpo.png | Bin 0 -> 2183 bytes doc/src/images/qeasingcurve-inoutback.png | Bin 0 -> 2460 bytes doc/src/images/qeasingcurve-inoutbounce.png | Bin 0 -> 2522 bytes doc/src/images/qeasingcurve-inoutcirc.png | Bin 0 -> 2352 bytes doc/src/images/qeasingcurve-inoutcubic.png | Bin 0 -> 2410 bytes doc/src/images/qeasingcurve-inoutelastic.png | Bin 0 -> 2485 bytes doc/src/images/qeasingcurve-inoutexpo.png | Bin 0 -> 2383 bytes doc/src/images/qeasingcurve-inoutquad.png | Bin 0 -> 2392 bytes doc/src/images/qeasingcurve-inoutquart.png | Bin 0 -> 2331 bytes doc/src/images/qeasingcurve-inoutquint.png | Bin 0 -> 2244 bytes doc/src/images/qeasingcurve-inoutsine.png | Bin 0 -> 2405 bytes doc/src/images/qeasingcurve-inquad.png | Bin 0 -> 2283 bytes doc/src/images/qeasingcurve-inquart.png | Bin 0 -> 2261 bytes doc/src/images/qeasingcurve-inquint.png | Bin 0 -> 2178 bytes doc/src/images/qeasingcurve-insine.png | Bin 0 -> 2167 bytes doc/src/images/qeasingcurve-linear.png | Bin 0 -> 2165 bytes doc/src/images/qeasingcurve-outback.png | Bin 0 -> 2371 bytes doc/src/images/qeasingcurve-outbounce.png | Bin 0 -> 2481 bytes doc/src/images/qeasingcurve-outcirc.png | Bin 0 -> 2269 bytes doc/src/images/qeasingcurve-outcubic.png | Bin 0 -> 2336 bytes doc/src/images/qeasingcurve-outcurve.png | Bin 0 -> 2389 bytes doc/src/images/qeasingcurve-outelastic.png | Bin 0 -> 2402 bytes doc/src/images/qeasingcurve-outexpo.png | Bin 0 -> 2299 bytes doc/src/images/qeasingcurve-outinback.png | Bin 0 -> 2400 bytes doc/src/images/qeasingcurve-outinbounce.png | Bin 0 -> 2568 bytes doc/src/images/qeasingcurve-outincirc.png | Bin 0 -> 2339 bytes doc/src/images/qeasingcurve-outincubic.png | Bin 0 -> 2393 bytes doc/src/images/qeasingcurve-outinelastic.png | Bin 0 -> 2517 bytes doc/src/images/qeasingcurve-outinexpo.png | Bin 0 -> 2377 bytes doc/src/images/qeasingcurve-outinquad.png | Bin 0 -> 2380 bytes doc/src/images/qeasingcurve-outinquart.png | Bin 0 -> 2319 bytes doc/src/images/qeasingcurve-outinquint.png | Bin 0 -> 2248 bytes doc/src/images/qeasingcurve-outinsine.png | Bin 0 -> 2388 bytes doc/src/images/qeasingcurve-outquad.png | Bin 0 -> 2324 bytes doc/src/images/qeasingcurve-outquart.png | Bin 0 -> 2304 bytes doc/src/images/qeasingcurve-outquint.png | Bin 0 -> 2242 bytes doc/src/images/qeasingcurve-outsine.png | Bin 0 -> 2364 bytes doc/src/images/qeasingcurve-sinecurve.png | Bin 0 -> 2470 bytes doc/src/images/statemachine-button-history.png | Bin 0 -> 8493 bytes doc/src/images/statemachine-button-nested.png | Bin 0 -> 7051 bytes doc/src/images/statemachine-button.png | Bin 0 -> 4233 bytes doc/src/images/statemachine-customevents.png | Bin 0 -> 2544 bytes doc/src/images/statemachine-customevents2.png | Bin 0 -> 6713 bytes doc/src/images/statemachine-finished.png | Bin 0 -> 5518 bytes doc/src/images/statemachine-nonparallel.png | Bin 0 -> 5350 bytes doc/src/images/statemachine-parallel.png | Bin 0 -> 8631 bytes doc/src/images/stickman-example.png | Bin 0 -> 18867 bytes doc/src/images/stickman-example1.png | Bin 0 -> 64543 bytes doc/src/images/stickman-example2.png | Bin 0 -> 37412 bytes doc/src/images/stickman-example3.png | Bin 0 -> 23591 bytes doc/src/images/tankgame-example.png | Bin 0 -> 16089 bytes doc/src/images/trafficlight-example.png | Bin 0 -> 5325 bytes doc/src/images/trafficlight-example1.png | Bin 0 -> 3694 bytes doc/src/images/trafficlight-example2.png | Bin 0 -> 7257 bytes doc/src/snippets/animation/sequential/icons.qrc | 6 + .../snippets/animation/sequential/icons/left.png | Bin 0 -> 413 bytes .../snippets/animation/sequential/icons/right.png | Bin 0 -> 414 bytes doc/src/snippets/animation/sequential/main.cpp | 50 + .../snippets/animation/sequential/sequential.pro | 4 + doc/src/snippets/animation/sequential/tracer.cpp | 25 + doc/src/snippets/animation/sequential/tracer.h | 23 + .../code/src_corelib_tools_qeasingcurve.cpp | 4 + doc/src/statemachine.qdoc | 645 ++++ examples/animation/README | 38 + examples/animation/animatedtiles/animatedtiles.pro | 8 + examples/animation/animatedtiles/animatedtiles.qrc | 11 + .../animatedtiles/images/Time-For-Lunch-2.jpg | Bin 0 -> 32471 bytes .../animation/animatedtiles/images/centered.png | Bin 0 -> 892 bytes .../animation/animatedtiles/images/ellipse.png | Bin 0 -> 10767 bytes .../animation/animatedtiles/images/figure8.png | Bin 0 -> 14050 bytes .../animation/animatedtiles/images/kinetic.png | Bin 0 -> 6776 bytes examples/animation/animatedtiles/images/random.png | Bin 0 -> 14969 bytes examples/animation/animatedtiles/images/tile.png | Bin 0 -> 16337 bytes examples/animation/animatedtiles/main.cpp | 280 ++ examples/animation/animation.pro | 16 + .../appchooser/accessories-dictionary.png | Bin 0 -> 5396 bytes examples/animation/appchooser/akregator.png | Bin 0 -> 4873 bytes examples/animation/appchooser/appchooser.pro | 8 + examples/animation/appchooser/appchooser.qrc | 8 + examples/animation/appchooser/digikam.png | Bin 0 -> 3334 bytes examples/animation/appchooser/k3b.png | Bin 0 -> 8220 bytes examples/animation/appchooser/main.cpp | 158 + examples/animation/easing/animation.h | 101 + examples/animation/easing/easing.pro | 14 + examples/animation/easing/easing.qrc | 5 + examples/animation/easing/form.ui | 201 ++ examples/animation/easing/images/qt-logo.png | Bin 0 -> 5149 bytes examples/animation/easing/main.cpp | 53 + examples/animation/easing/window.cpp | 163 + examples/animation/easing/window.h | 79 + examples/animation/moveblocks/main.cpp | 296 ++ examples/animation/moveblocks/moveblocks.pro | 7 + .../animation/states/accessories-dictionary.png | Bin 0 -> 5396 bytes examples/animation/states/akregator.png | Bin 0 -> 4873 bytes examples/animation/states/digikam.png | Bin 0 -> 3334 bytes examples/animation/states/help-browser.png | Bin 0 -> 6984 bytes examples/animation/states/k3b.png | Bin 0 -> 8220 bytes examples/animation/states/kchart.png | Bin 0 -> 4887 bytes examples/animation/states/main.cpp | 284 ++ examples/animation/states/states.pro | 8 + examples/animation/states/states.qrc | 10 + examples/animation/stickman/animation.cpp | 193 ++ examples/animation/stickman/animation.h | 83 + examples/animation/stickman/animations/chilling | Bin 0 -> 6508 bytes examples/animation/stickman/animations/dancing | Bin 0 -> 2348 bytes examples/animation/stickman/animations/dead | Bin 0 -> 268 bytes examples/animation/stickman/animations/jumping | Bin 0 -> 1308 bytes .../animation/stickman/editor/animationdialog.cpp | 192 ++ .../animation/stickman/editor/animationdialog.h | 84 + examples/animation/stickman/editor/editor.pri | 2 + examples/animation/stickman/editor/mainwindow.cpp | 76 + examples/animation/stickman/editor/mainwindow.h | 58 + examples/animation/stickman/graphicsview.cpp | 81 + examples/animation/stickman/graphicsview.h | 64 + examples/animation/stickman/lifecycle.cpp | 212 ++ examples/animation/stickman/lifecycle.h | 80 + examples/animation/stickman/main.cpp | 97 + examples/animation/stickman/node.cpp | 92 + examples/animation/stickman/node.h | 72 + examples/animation/stickman/stickman.cpp | 339 ++ examples/animation/stickman/stickman.h | 103 + examples/animation/stickman/stickman.pro | 19 + examples/animation/sub-attaq/animationmanager.cpp | 93 + examples/animation/sub-attaq/animationmanager.h | 70 + examples/animation/sub-attaq/boat.cpp | 318 ++ examples/animation/sub-attaq/boat.h | 102 + examples/animation/sub-attaq/boat_p.h | 256 ++ examples/animation/sub-attaq/bomb.cpp | 124 + examples/animation/sub-attaq/bomb.h | 76 + .../sub-attaq/custompropertyanimation.cpp | 108 + .../animation/sub-attaq/custompropertyanimation.h | 114 + examples/animation/sub-attaq/data.xml | 15 + examples/animation/sub-attaq/graphicsscene.cpp | 374 +++ examples/animation/sub-attaq/graphicsscene.h | 131 + examples/animation/sub-attaq/main.cpp | 57 + examples/animation/sub-attaq/mainwindow.cpp | 92 + examples/animation/sub-attaq/mainwindow.h | 64 + .../animation/sub-attaq/pics/big/background.png | Bin 0 -> 48858 bytes examples/animation/sub-attaq/pics/big/boat.png | Bin 0 -> 5198 bytes examples/animation/sub-attaq/pics/big/bomb.png | Bin 0 -> 760 bytes .../sub-attaq/pics/big/explosion/boat/step1.png | Bin 0 -> 5760 bytes .../sub-attaq/pics/big/explosion/boat/step2.png | Bin 0 -> 9976 bytes .../sub-attaq/pics/big/explosion/boat/step3.png | Bin 0 -> 12411 bytes .../sub-attaq/pics/big/explosion/boat/step4.png | Bin 0 -> 15438 bytes .../pics/big/explosion/submarine/step1.png | Bin 0 -> 3354 bytes .../pics/big/explosion/submarine/step2.png | Bin 0 -> 6205 bytes .../pics/big/explosion/submarine/step3.png | Bin 0 -> 6678 bytes .../pics/big/explosion/submarine/step4.png | Bin 0 -> 6666 bytes .../animation/sub-attaq/pics/big/submarine.png | Bin 0 -> 3202 bytes examples/animation/sub-attaq/pics/big/surface.png | Bin 0 -> 575 bytes examples/animation/sub-attaq/pics/big/torpedo.png | Bin 0 -> 951 bytes .../sub-attaq/pics/scalable/background-n810.svg | 171 + .../sub-attaq/pics/scalable/background.svg | 171 + .../animation/sub-attaq/pics/scalable/boat.svg | 279 ++ .../animation/sub-attaq/pics/scalable/bomb.svg | 138 + .../animation/sub-attaq/pics/scalable/sand.svg | 103 + examples/animation/sub-attaq/pics/scalable/see.svg | 44 + examples/animation/sub-attaq/pics/scalable/sky.svg | 45 + .../sub-attaq/pics/scalable/sub-attaq.svg | 1473 ++++++++ .../sub-attaq/pics/scalable/submarine.svg | 214 ++ .../animation/sub-attaq/pics/scalable/surface.svg | 49 + .../animation/sub-attaq/pics/scalable/torpedo.svg | 127 + .../animation/sub-attaq/pics/small/background.png | Bin 0 -> 34634 bytes examples/animation/sub-attaq/pics/small/boat.png | Bin 0 -> 2394 bytes examples/animation/sub-attaq/pics/small/bomb.png | Bin 0 -> 760 bytes .../animation/sub-attaq/pics/small/submarine.png | Bin 0 -> 1338 bytes .../animation/sub-attaq/pics/small/surface.png | Bin 0 -> 502 bytes .../animation/sub-attaq/pics/small/torpedo.png | Bin 0 -> 951 bytes .../animation/sub-attaq/pics/welcome/logo-a.png | Bin 0 -> 5972 bytes .../animation/sub-attaq/pics/welcome/logo-a2.png | Bin 0 -> 5969 bytes .../animation/sub-attaq/pics/welcome/logo-b.png | Bin 0 -> 6869 bytes .../animation/sub-attaq/pics/welcome/logo-dash.png | Bin 0 -> 2255 bytes .../animation/sub-attaq/pics/welcome/logo-excl.png | Bin 0 -> 2740 bytes .../animation/sub-attaq/pics/welcome/logo-q.png | Bin 0 -> 7016 bytes .../animation/sub-attaq/pics/welcome/logo-s.png | Bin 0 -> 5817 bytes .../animation/sub-attaq/pics/welcome/logo-t.png | Bin 0 -> 3717 bytes .../animation/sub-attaq/pics/welcome/logo-t2.png | Bin 0 -> 3688 bytes .../animation/sub-attaq/pics/welcome/logo-u.png | Bin 0 -> 5374 bytes examples/animation/sub-attaq/pixmapitem.cpp | 59 + examples/animation/sub-attaq/pixmapitem.h | 63 + examples/animation/sub-attaq/progressitem.cpp | 67 + examples/animation/sub-attaq/progressitem.h | 61 + examples/animation/sub-attaq/qanimationstate.cpp | 171 + examples/animation/sub-attaq/qanimationstate.h | 92 + examples/animation/sub-attaq/states.cpp | 325 ++ examples/animation/sub-attaq/states.h | 180 + examples/animation/sub-attaq/sub-attaq.pro | 36 + examples/animation/sub-attaq/subattaq.qrc | 38 + examples/animation/sub-attaq/submarine.cpp | 211 ++ examples/animation/sub-attaq/submarine.h | 92 + examples/animation/sub-attaq/submarine_p.h | 139 + examples/animation/sub-attaq/torpedo.cpp | 120 + examples/animation/sub-attaq/torpedo.h | 76 + examples/examples.pro | 2 + examples/statemachine/README | 36 + .../eventtransitions/eventtransitions.pro | 7 + examples/statemachine/eventtransitions/main.cpp | 116 + examples/statemachine/factorial/factorial.pro | 11 + examples/statemachine/factorial/main.cpp | 182 + examples/statemachine/pingpong/main.cpp | 145 + examples/statemachine/pingpong/pingpong.pro | 11 + examples/statemachine/statemachine.pro | 15 + examples/statemachine/tankgame/gameitem.cpp | 129 + examples/statemachine/tankgame/gameitem.h | 66 + .../statemachine/tankgame/gameovertransition.cpp | 80 + .../statemachine/tankgame/gameovertransition.h | 63 + examples/statemachine/tankgame/main.cpp | 53 + examples/statemachine/tankgame/mainwindow.cpp | 342 ++ examples/statemachine/tankgame/mainwindow.h | 93 + examples/statemachine/tankgame/plugin.h | 62 + examples/statemachine/tankgame/rocketitem.cpp | 101 + examples/statemachine/tankgame/rocketitem.h | 66 + examples/statemachine/tankgame/tankgame.pro | 19 + examples/statemachine/tankgame/tankitem.cpp | 302 ++ examples/statemachine/tankgame/tankitem.h | 109 + .../tankgameplugins/random_ai/random_ai.pro | 13 + .../tankgameplugins/random_ai/random_ai_plugin.cpp | 79 + .../tankgameplugins/random_ai/random_ai_plugin.h | 105 + .../tankgameplugins/seek_ai/seek_ai.cpp | 89 + .../statemachine/tankgameplugins/seek_ai/seek_ai.h | 249 ++ .../tankgameplugins/seek_ai/seek_ai.pro | 13 + .../tankgameplugins/spin_ai/spin_ai.cpp | 70 + .../statemachine/tankgameplugins/spin_ai/spin_ai.h | 92 + .../tankgameplugins/spin_ai/spin_ai.pro | 13 + .../spin_ai_with_error/spin_ai_with_error.cpp | 70 + .../spin_ai_with_error/spin_ai_with_error.h | 92 + .../spin_ai_with_error/spin_ai_with_error.pro | 13 + .../tankgameplugins/tankgameplugins.pro | 11 + examples/statemachine/trafficlight/main.cpp | 190 ++ .../statemachine/trafficlight/trafficlight.pro | 7 + examples/statemachine/twowaybutton/main.cpp | 86 + .../statemachine/twowaybutton/twowaybutton.pro | 7 + mkspecs/win32-icc/qmake.conf | 2 +- src/3rdparty/easing/easing.cpp | 670 ++++ src/3rdparty/easing/legal.qdoc | 35 + src/corelib/animation/animation.pri | 25 + src/corelib/animation/qabstractanimation.cpp | 759 +++++ src/corelib/animation/qabstractanimation.h | 137 + src/corelib/animation/qabstractanimation_p.h | 136 + src/corelib/animation/qanimationgroup.cpp | 309 ++ src/corelib/animation/qanimationgroup.h | 88 + src/corelib/animation/qanimationgroup_p.h | 79 + src/corelib/animation/qparallelanimationgroup.cpp | 316 ++ src/corelib/animation/qparallelanimationgroup.h | 86 + src/corelib/animation/qparallelanimationgroup_p.h | 85 + src/corelib/animation/qpauseanimation.cpp | 154 + src/corelib/animation/qpauseanimation.h | 84 + src/corelib/animation/qpropertyanimation.cpp | 316 ++ src/corelib/animation/qpropertyanimation.h | 90 + src/corelib/animation/qpropertyanimation_p.h | 89 + .../animation/qsequentialanimationgroup.cpp | 594 ++++ src/corelib/animation/qsequentialanimationgroup.h | 96 + .../animation/qsequentialanimationgroup_p.h | 111 + src/corelib/animation/qvariantanimation.cpp | 644 ++++ src/corelib/animation/qvariantanimation.h | 130 + src/corelib/animation/qvariantanimation_p.h | 130 + src/corelib/corelib.pro | 2 + src/corelib/kernel/kernel.pri | 8 +- src/corelib/kernel/qcoreevent.cpp | 2 + src/corelib/kernel/qcoreevent.h | 8 +- src/corelib/statemachine/qabstractstate.cpp | 202 ++ src/corelib/statemachine/qabstractstate.h | 90 + src/corelib/statemachine/qabstractstate_p.h | 84 + src/corelib/statemachine/qabstracttransition.cpp | 342 ++ src/corelib/statemachine/qabstracttransition.h | 111 + src/corelib/statemachine/qabstracttransition_p.h | 91 + src/corelib/statemachine/qeventtransition.cpp | 282 ++ src/corelib/statemachine/qeventtransition.h | 96 + src/corelib/statemachine/qeventtransition_p.h | 78 + src/corelib/statemachine/qfinalstate.cpp | 134 + src/corelib/statemachine/qfinalstate.h | 76 + src/corelib/statemachine/qhistorystate.cpp | 223 ++ src/corelib/statemachine/qhistorystate.h | 91 + src/corelib/statemachine/qhistorystate_p.h | 79 + src/corelib/statemachine/qsignalevent.h | 77 + src/corelib/statemachine/qsignaleventgenerator_p.h | 78 + src/corelib/statemachine/qsignaltransition.cpp | 257 ++ src/corelib/statemachine/qsignaltransition.h | 89 + src/corelib/statemachine/qsignaltransition_p.h | 78 + src/corelib/statemachine/qstate.cpp | 497 +++ src/corelib/statemachine/qstate.h | 113 + src/corelib/statemachine/qstate_p.h | 108 + src/corelib/statemachine/qstatemachine.cpp | 2216 ++++++++++++ src/corelib/statemachine/qstatemachine.h | 166 + src/corelib/statemachine/qstatemachine_p.h | 217 ++ src/corelib/statemachine/qwrappedevent.h | 76 + src/corelib/statemachine/statemachine.pri | 30 + src/corelib/tools/qeasingcurve.cpp | 846 +++++ src/corelib/tools/qeasingcurve.h | 114 + src/corelib/tools/qtimeline.cpp | 114 +- src/corelib/tools/qtimeline.h | 5 + src/corelib/tools/tools.pri | 2 + src/gui/animation/animation.pri | 3 + src/gui/animation/qguivariantanimation.cpp | 75 + src/gui/graphicsview/qgraphicsitem_p.h | 12 +- src/gui/graphicsview/qgraphicsproxywidget.cpp | 2 + src/gui/graphicsview/qgraphicsproxywidget.h | 2 + src/gui/gui.pro | 2 + src/gui/kernel/qapplication.cpp | 6 + src/gui/painting/qdrawhelper.cpp | 8 +- src/gui/statemachine/qbasickeyeventtransition.cpp | 203 ++ src/gui/statemachine/qbasickeyeventtransition_p.h | 93 + .../statemachine/qbasicmouseeventtransition.cpp | 208 ++ .../statemachine/qbasicmouseeventtransition_p.h | 98 + src/gui/statemachine/qguistatemachine.cpp | 559 +++ src/gui/statemachine/qkeyeventtransition.cpp | 186 + src/gui/statemachine/qkeyeventtransition.h | 87 + src/gui/statemachine/qmouseeventtransition.cpp | 216 ++ src/gui/statemachine/qmouseeventtransition.h | 92 + src/gui/statemachine/statemachine.pri | 13 + tests/auto/auto.pro | 6 + tests/auto/qanimationgroup/qanimationgroup.pro | 5 + tests/auto/qanimationgroup/tst_qanimationgroup.cpp | 413 +++ tests/auto/qeasingcurve/qeasingcurve.pro | 3 + tests/auto/qeasingcurve/tst_qeasingcurve.cpp | 487 +++ tests/auto/qmake/testdata/bundle-spaces/some-file | 6 + .../qparallelanimationgroup.pro | 5 + .../tst_qparallelanimationgroup.cpp | 834 +++++ .../auto/qpropertyanimation/qpropertyanimation.pro | 5 + .../qpropertyanimation/tst_qpropertyanimation.cpp | 919 +++++ .../qsequentialanimationgroup.pro | 5 + .../tst_qsequentialanimationgroup.cpp | 1649 +++++++++ tests/auto/qstate/qstate.pro | 5 + tests/auto/qstate/tst_qstate.cpp | 340 ++ tests/auto/qstatemachine/qstatemachine.pro | 4 + tests/auto/qstatemachine/tst_qstatemachine.cpp | 3548 ++++++++++++++++++++ tests/benchmarks/benchmarks.pro | 1 + tests/benchmarks/qanimation/dummyanimation.cpp | 20 + tests/benchmarks/qanimation/dummyanimation.h | 19 + tests/benchmarks/qanimation/dummyobject.cpp | 25 + tests/benchmarks/qanimation/dummyobject.h | 23 + tests/benchmarks/qanimation/main.cpp | 150 + tests/benchmarks/qanimation/qanimation.pro | 18 + tests/benchmarks/qanimation/rectanimation.cpp | 58 + tests/benchmarks/qanimation/rectanimation.h | 30 + tests/benchmarks/qvariant/qvariant.pro | 1 - tests/benchmarks/qvariant/tst_qvariant.cpp | 115 +- 363 files changed, 38378 insertions(+), 130 deletions(-) create mode 100644 doc/src/animation.qdoc create mode 100644 doc/src/diagrams/animations-architecture.svg create mode 100644 doc/src/diagrams/programs/easingcurve/easingcurve.pro create mode 100644 doc/src/diagrams/programs/easingcurve/main.cpp create mode 100644 doc/src/examples/eventtransitions.qdoc create mode 100644 doc/src/examples/factorial.qdoc create mode 100644 doc/src/examples/pingpong.qdoc create mode 100644 doc/src/examples/stickman.qdoc create mode 100644 doc/src/examples/tankgame.qdoc create mode 100644 doc/src/examples/trafficlight.qdoc create mode 100644 doc/src/examples/twowaybutton.qdoc create mode 100644 doc/src/images/animations-architecture.png create mode 100644 doc/src/images/factorial-example.png create mode 100644 doc/src/images/pingpong-example.png create mode 100644 doc/src/images/qeasingcurve-cosinecurve.png create mode 100644 doc/src/images/qeasingcurve-inback.png create mode 100644 doc/src/images/qeasingcurve-inbounce.png create mode 100644 doc/src/images/qeasingcurve-incirc.png create mode 100644 doc/src/images/qeasingcurve-incubic.png create mode 100644 doc/src/images/qeasingcurve-incurve.png create mode 100644 doc/src/images/qeasingcurve-inelastic.png create mode 100644 doc/src/images/qeasingcurve-inexpo.png create mode 100644 doc/src/images/qeasingcurve-inoutback.png create mode 100644 doc/src/images/qeasingcurve-inoutbounce.png create mode 100644 doc/src/images/qeasingcurve-inoutcirc.png create mode 100644 doc/src/images/qeasingcurve-inoutcubic.png create mode 100644 doc/src/images/qeasingcurve-inoutelastic.png create mode 100644 doc/src/images/qeasingcurve-inoutexpo.png create mode 100644 doc/src/images/qeasingcurve-inoutquad.png create mode 100644 doc/src/images/qeasingcurve-inoutquart.png create mode 100644 doc/src/images/qeasingcurve-inoutquint.png create mode 100644 doc/src/images/qeasingcurve-inoutsine.png create mode 100644 doc/src/images/qeasingcurve-inquad.png create mode 100644 doc/src/images/qeasingcurve-inquart.png create mode 100644 doc/src/images/qeasingcurve-inquint.png create mode 100644 doc/src/images/qeasingcurve-insine.png create mode 100644 doc/src/images/qeasingcurve-linear.png create mode 100644 doc/src/images/qeasingcurve-outback.png create mode 100644 doc/src/images/qeasingcurve-outbounce.png create mode 100644 doc/src/images/qeasingcurve-outcirc.png create mode 100644 doc/src/images/qeasingcurve-outcubic.png create mode 100644 doc/src/images/qeasingcurve-outcurve.png create mode 100644 doc/src/images/qeasingcurve-outelastic.png create mode 100644 doc/src/images/qeasingcurve-outexpo.png create mode 100644 doc/src/images/qeasingcurve-outinback.png create mode 100644 doc/src/images/qeasingcurve-outinbounce.png create mode 100644 doc/src/images/qeasingcurve-outincirc.png create mode 100644 doc/src/images/qeasingcurve-outincubic.png create mode 100644 doc/src/images/qeasingcurve-outinelastic.png create mode 100644 doc/src/images/qeasingcurve-outinexpo.png create mode 100644 doc/src/images/qeasingcurve-outinquad.png create mode 100644 doc/src/images/qeasingcurve-outinquart.png create mode 100644 doc/src/images/qeasingcurve-outinquint.png create mode 100644 doc/src/images/qeasingcurve-outinsine.png create mode 100644 doc/src/images/qeasingcurve-outquad.png create mode 100644 doc/src/images/qeasingcurve-outquart.png create mode 100644 doc/src/images/qeasingcurve-outquint.png create mode 100644 doc/src/images/qeasingcurve-outsine.png create mode 100644 doc/src/images/qeasingcurve-sinecurve.png create mode 100644 doc/src/images/statemachine-button-history.png create mode 100644 doc/src/images/statemachine-button-nested.png create mode 100644 doc/src/images/statemachine-button.png create mode 100644 doc/src/images/statemachine-customevents.png create mode 100644 doc/src/images/statemachine-customevents2.png create mode 100644 doc/src/images/statemachine-finished.png create mode 100644 doc/src/images/statemachine-nonparallel.png create mode 100644 doc/src/images/statemachine-parallel.png create mode 100644 doc/src/images/stickman-example.png create mode 100644 doc/src/images/stickman-example1.png create mode 100644 doc/src/images/stickman-example2.png create mode 100644 doc/src/images/stickman-example3.png create mode 100644 doc/src/images/tankgame-example.png create mode 100644 doc/src/images/trafficlight-example.png create mode 100644 doc/src/images/trafficlight-example1.png create mode 100644 doc/src/images/trafficlight-example2.png create mode 100644 doc/src/snippets/animation/sequential/icons.qrc create mode 100644 doc/src/snippets/animation/sequential/icons/left.png create mode 100644 doc/src/snippets/animation/sequential/icons/right.png create mode 100644 doc/src/snippets/animation/sequential/main.cpp create mode 100644 doc/src/snippets/animation/sequential/sequential.pro create mode 100644 doc/src/snippets/animation/sequential/tracer.cpp create mode 100644 doc/src/snippets/animation/sequential/tracer.h create mode 100644 doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp create mode 100644 doc/src/statemachine.qdoc create mode 100644 examples/animation/README create mode 100644 examples/animation/animatedtiles/animatedtiles.pro create mode 100644 examples/animation/animatedtiles/animatedtiles.qrc create mode 100644 examples/animation/animatedtiles/images/Time-For-Lunch-2.jpg create mode 100644 examples/animation/animatedtiles/images/centered.png create mode 100644 examples/animation/animatedtiles/images/ellipse.png create mode 100644 examples/animation/animatedtiles/images/figure8.png create mode 100644 examples/animation/animatedtiles/images/kinetic.png create mode 100644 examples/animation/animatedtiles/images/random.png create mode 100644 examples/animation/animatedtiles/images/tile.png create mode 100644 examples/animation/animatedtiles/main.cpp create mode 100644 examples/animation/animation.pro create mode 100644 examples/animation/appchooser/accessories-dictionary.png create mode 100644 examples/animation/appchooser/akregator.png create mode 100644 examples/animation/appchooser/appchooser.pro create mode 100644 examples/animation/appchooser/appchooser.qrc create mode 100644 examples/animation/appchooser/digikam.png create mode 100644 examples/animation/appchooser/k3b.png create mode 100644 examples/animation/appchooser/main.cpp create mode 100644 examples/animation/easing/animation.h create mode 100644 examples/animation/easing/easing.pro create mode 100644 examples/animation/easing/easing.qrc create mode 100644 examples/animation/easing/form.ui create mode 100644 examples/animation/easing/images/qt-logo.png create mode 100644 examples/animation/easing/main.cpp create mode 100644 examples/animation/easing/window.cpp create mode 100644 examples/animation/easing/window.h create mode 100644 examples/animation/moveblocks/main.cpp create mode 100644 examples/animation/moveblocks/moveblocks.pro create mode 100644 examples/animation/states/accessories-dictionary.png create mode 100644 examples/animation/states/akregator.png create mode 100644 examples/animation/states/digikam.png create mode 100644 examples/animation/states/help-browser.png create mode 100644 examples/animation/states/k3b.png create mode 100644 examples/animation/states/kchart.png create mode 100644 examples/animation/states/main.cpp create mode 100644 examples/animation/states/states.pro create mode 100644 examples/animation/states/states.qrc create mode 100644 examples/animation/stickman/animation.cpp create mode 100644 examples/animation/stickman/animation.h create mode 100644 examples/animation/stickman/animations/chilling create mode 100644 examples/animation/stickman/animations/dancing create mode 100644 examples/animation/stickman/animations/dead create mode 100644 examples/animation/stickman/animations/jumping create mode 100644 examples/animation/stickman/editor/animationdialog.cpp create mode 100644 examples/animation/stickman/editor/animationdialog.h create mode 100644 examples/animation/stickman/editor/editor.pri create mode 100644 examples/animation/stickman/editor/mainwindow.cpp create mode 100644 examples/animation/stickman/editor/mainwindow.h create mode 100644 examples/animation/stickman/graphicsview.cpp create mode 100644 examples/animation/stickman/graphicsview.h create mode 100644 examples/animation/stickman/lifecycle.cpp create mode 100644 examples/animation/stickman/lifecycle.h create mode 100644 examples/animation/stickman/main.cpp create mode 100644 examples/animation/stickman/node.cpp create mode 100644 examples/animation/stickman/node.h create mode 100644 examples/animation/stickman/stickman.cpp create mode 100644 examples/animation/stickman/stickman.h create mode 100644 examples/animation/stickman/stickman.pro create mode 100644 examples/animation/sub-attaq/animationmanager.cpp create mode 100644 examples/animation/sub-attaq/animationmanager.h create mode 100644 examples/animation/sub-attaq/boat.cpp create mode 100644 examples/animation/sub-attaq/boat.h create mode 100644 examples/animation/sub-attaq/boat_p.h create mode 100644 examples/animation/sub-attaq/bomb.cpp create mode 100644 examples/animation/sub-attaq/bomb.h create mode 100644 examples/animation/sub-attaq/custompropertyanimation.cpp create mode 100644 examples/animation/sub-attaq/custompropertyanimation.h create mode 100644 examples/animation/sub-attaq/data.xml create mode 100644 examples/animation/sub-attaq/graphicsscene.cpp create mode 100644 examples/animation/sub-attaq/graphicsscene.h create mode 100644 examples/animation/sub-attaq/main.cpp create mode 100644 examples/animation/sub-attaq/mainwindow.cpp create mode 100644 examples/animation/sub-attaq/mainwindow.h create mode 100644 examples/animation/sub-attaq/pics/big/background.png create mode 100644 examples/animation/sub-attaq/pics/big/boat.png create mode 100644 examples/animation/sub-attaq/pics/big/bomb.png create mode 100644 examples/animation/sub-attaq/pics/big/explosion/boat/step1.png create mode 100644 examples/animation/sub-attaq/pics/big/explosion/boat/step2.png create mode 100644 examples/animation/sub-attaq/pics/big/explosion/boat/step3.png create mode 100644 examples/animation/sub-attaq/pics/big/explosion/boat/step4.png create mode 100644 examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png create mode 100644 examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png create mode 100644 examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png create mode 100644 examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png create mode 100644 examples/animation/sub-attaq/pics/big/submarine.png create mode 100644 examples/animation/sub-attaq/pics/big/surface.png create mode 100644 examples/animation/sub-attaq/pics/big/torpedo.png create mode 100644 examples/animation/sub-attaq/pics/scalable/background-n810.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/background.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/boat.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/bomb.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/sand.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/see.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/sky.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/sub-attaq.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/submarine.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/surface.svg create mode 100644 examples/animation/sub-attaq/pics/scalable/torpedo.svg create mode 100644 examples/animation/sub-attaq/pics/small/background.png create mode 100644 examples/animation/sub-attaq/pics/small/boat.png create mode 100644 examples/animation/sub-attaq/pics/small/bomb.png create mode 100644 examples/animation/sub-attaq/pics/small/submarine.png create mode 100644 examples/animation/sub-attaq/pics/small/surface.png create mode 100644 examples/animation/sub-attaq/pics/small/torpedo.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-a.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-a2.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-b.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-dash.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-excl.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-q.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-s.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-t.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-t2.png create mode 100644 examples/animation/sub-attaq/pics/welcome/logo-u.png create mode 100644 examples/animation/sub-attaq/pixmapitem.cpp create mode 100644 examples/animation/sub-attaq/pixmapitem.h create mode 100644 examples/animation/sub-attaq/progressitem.cpp create mode 100644 examples/animation/sub-attaq/progressitem.h create mode 100644 examples/animation/sub-attaq/qanimationstate.cpp create mode 100644 examples/animation/sub-attaq/qanimationstate.h create mode 100644 examples/animation/sub-attaq/states.cpp create mode 100644 examples/animation/sub-attaq/states.h create mode 100644 examples/animation/sub-attaq/sub-attaq.pro create mode 100644 examples/animation/sub-attaq/subattaq.qrc create mode 100644 examples/animation/sub-attaq/submarine.cpp create mode 100644 examples/animation/sub-attaq/submarine.h create mode 100644 examples/animation/sub-attaq/submarine_p.h create mode 100644 examples/animation/sub-attaq/torpedo.cpp create mode 100644 examples/animation/sub-attaq/torpedo.h create mode 100644 examples/statemachine/README create mode 100644 examples/statemachine/eventtransitions/eventtransitions.pro create mode 100644 examples/statemachine/eventtransitions/main.cpp create mode 100644 examples/statemachine/factorial/factorial.pro create mode 100644 examples/statemachine/factorial/main.cpp create mode 100644 examples/statemachine/pingpong/main.cpp create mode 100644 examples/statemachine/pingpong/pingpong.pro create mode 100644 examples/statemachine/statemachine.pro create mode 100644 examples/statemachine/tankgame/gameitem.cpp create mode 100644 examples/statemachine/tankgame/gameitem.h create mode 100644 examples/statemachine/tankgame/gameovertransition.cpp create mode 100644 examples/statemachine/tankgame/gameovertransition.h create mode 100644 examples/statemachine/tankgame/main.cpp create mode 100644 examples/statemachine/tankgame/mainwindow.cpp create mode 100644 examples/statemachine/tankgame/mainwindow.h create mode 100644 examples/statemachine/tankgame/plugin.h create mode 100644 examples/statemachine/tankgame/rocketitem.cpp create mode 100644 examples/statemachine/tankgame/rocketitem.h create mode 100644 examples/statemachine/tankgame/tankgame.pro create mode 100644 examples/statemachine/tankgame/tankitem.cpp create mode 100644 examples/statemachine/tankgame/tankitem.h create mode 100644 examples/statemachine/tankgameplugins/random_ai/random_ai.pro create mode 100644 examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp create mode 100644 examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h create mode 100644 examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp create mode 100644 examples/statemachine/tankgameplugins/seek_ai/seek_ai.h create mode 100644 examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro create mode 100644 examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp create mode 100644 examples/statemachine/tankgameplugins/spin_ai/spin_ai.h create mode 100644 examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro create mode 100644 examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp create mode 100644 examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h create mode 100644 examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro create mode 100644 examples/statemachine/tankgameplugins/tankgameplugins.pro create mode 100644 examples/statemachine/trafficlight/main.cpp create mode 100644 examples/statemachine/trafficlight/trafficlight.pro create mode 100644 examples/statemachine/twowaybutton/main.cpp create mode 100644 examples/statemachine/twowaybutton/twowaybutton.pro create mode 100644 src/3rdparty/easing/easing.cpp create mode 100644 src/3rdparty/easing/legal.qdoc create mode 100644 src/corelib/animation/animation.pri create mode 100644 src/corelib/animation/qabstractanimation.cpp create mode 100644 src/corelib/animation/qabstractanimation.h create mode 100644 src/corelib/animation/qabstractanimation_p.h create mode 100644 src/corelib/animation/qanimationgroup.cpp create mode 100644 src/corelib/animation/qanimationgroup.h create mode 100644 src/corelib/animation/qanimationgroup_p.h create mode 100644 src/corelib/animation/qparallelanimationgroup.cpp create mode 100644 src/corelib/animation/qparallelanimationgroup.h create mode 100644 src/corelib/animation/qparallelanimationgroup_p.h create mode 100644 src/corelib/animation/qpauseanimation.cpp create mode 100644 src/corelib/animation/qpauseanimation.h create mode 100644 src/corelib/animation/qpropertyanimation.cpp create mode 100644 src/corelib/animation/qpropertyanimation.h create mode 100644 src/corelib/animation/qpropertyanimation_p.h create mode 100644 src/corelib/animation/qsequentialanimationgroup.cpp create mode 100644 src/corelib/animation/qsequentialanimationgroup.h create mode 100644 src/corelib/animation/qsequentialanimationgroup_p.h create mode 100644 src/corelib/animation/qvariantanimation.cpp create mode 100644 src/corelib/animation/qvariantanimation.h create mode 100644 src/corelib/animation/qvariantanimation_p.h create mode 100644 src/corelib/statemachine/qabstractstate.cpp create mode 100644 src/corelib/statemachine/qabstractstate.h create mode 100644 src/corelib/statemachine/qabstractstate_p.h create mode 100644 src/corelib/statemachine/qabstracttransition.cpp create mode 100644 src/corelib/statemachine/qabstracttransition.h create mode 100644 src/corelib/statemachine/qabstracttransition_p.h create mode 100644 src/corelib/statemachine/qeventtransition.cpp create mode 100644 src/corelib/statemachine/qeventtransition.h create mode 100644 src/corelib/statemachine/qeventtransition_p.h create mode 100644 src/corelib/statemachine/qfinalstate.cpp create mode 100644 src/corelib/statemachine/qfinalstate.h create mode 100644 src/corelib/statemachine/qhistorystate.cpp create mode 100644 src/corelib/statemachine/qhistorystate.h create mode 100644 src/corelib/statemachine/qhistorystate_p.h create mode 100644 src/corelib/statemachine/qsignalevent.h create mode 100644 src/corelib/statemachine/qsignaleventgenerator_p.h create mode 100644 src/corelib/statemachine/qsignaltransition.cpp create mode 100644 src/corelib/statemachine/qsignaltransition.h create mode 100644 src/corelib/statemachine/qsignaltransition_p.h create mode 100644 src/corelib/statemachine/qstate.cpp create mode 100644 src/corelib/statemachine/qstate.h create mode 100644 src/corelib/statemachine/qstate_p.h create mode 100644 src/corelib/statemachine/qstatemachine.cpp create mode 100644 src/corelib/statemachine/qstatemachine.h create mode 100644 src/corelib/statemachine/qstatemachine_p.h create mode 100644 src/corelib/statemachine/qwrappedevent.h create mode 100644 src/corelib/statemachine/statemachine.pri create mode 100644 src/corelib/tools/qeasingcurve.cpp create mode 100644 src/corelib/tools/qeasingcurve.h create mode 100644 src/gui/animation/animation.pri create mode 100644 src/gui/animation/qguivariantanimation.cpp create mode 100644 src/gui/statemachine/qbasickeyeventtransition.cpp create mode 100644 src/gui/statemachine/qbasickeyeventtransition_p.h create mode 100644 src/gui/statemachine/qbasicmouseeventtransition.cpp create mode 100644 src/gui/statemachine/qbasicmouseeventtransition_p.h create mode 100644 src/gui/statemachine/qguistatemachine.cpp create mode 100644 src/gui/statemachine/qkeyeventtransition.cpp create mode 100644 src/gui/statemachine/qkeyeventtransition.h create mode 100644 src/gui/statemachine/qmouseeventtransition.cpp create mode 100644 src/gui/statemachine/qmouseeventtransition.h create mode 100644 src/gui/statemachine/statemachine.pri create mode 100644 tests/auto/qanimationgroup/qanimationgroup.pro create mode 100644 tests/auto/qanimationgroup/tst_qanimationgroup.cpp create mode 100644 tests/auto/qeasingcurve/qeasingcurve.pro create mode 100644 tests/auto/qeasingcurve/tst_qeasingcurve.cpp create mode 100644 tests/auto/qparallelanimationgroup/qparallelanimationgroup.pro create mode 100644 tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp create mode 100644 tests/auto/qpropertyanimation/qpropertyanimation.pro create mode 100644 tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp create mode 100644 tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro create mode 100644 tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp create mode 100644 tests/auto/qstate/qstate.pro create mode 100644 tests/auto/qstate/tst_qstate.cpp create mode 100644 tests/auto/qstatemachine/qstatemachine.pro create mode 100644 tests/auto/qstatemachine/tst_qstatemachine.cpp create mode 100644 tests/benchmarks/qanimation/dummyanimation.cpp create mode 100644 tests/benchmarks/qanimation/dummyanimation.h create mode 100644 tests/benchmarks/qanimation/dummyobject.cpp create mode 100644 tests/benchmarks/qanimation/dummyobject.h create mode 100644 tests/benchmarks/qanimation/main.cpp create mode 100644 tests/benchmarks/qanimation/qanimation.pro create mode 100644 tests/benchmarks/qanimation/rectanimation.cpp create mode 100644 tests/benchmarks/qanimation/rectanimation.h diff --git a/demos/qtdemo/xml/examples.xml b/demos/qtdemo/xml/examples.xml index 96a3e80..2560848 100644 --- a/demos/qtdemo/xml/examples.xml +++ b/demos/qtdemo/xml/examples.xml @@ -19,6 +19,15 @@ + + + + + + + + + @@ -167,6 +176,12 @@ + + + + + + diff --git a/doc/src/animation.qdoc b/doc/src/animation.qdoc new file mode 100644 index 0000000..b4e603c --- /dev/null +++ b/doc/src/animation.qdoc @@ -0,0 +1,368 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page animation-overview.html + \title The Animation Framework + \ingroup architecture + \ingroup animation + \brief An overview of the Animation Framework + + \keyword Animation + + The animation framework is part of the Kinetic project, and aims + to provide an easy way for creating animated and smooth GUI's. By + animating Qt properties, the framework provides great freedom for + animating widgets and other \l{QObject}s. The framework can also + be used with the Graphics View framework. + + In this overview, we explain the basics of its architecture. We + also show examples of the most common techniques that the + framework allows for animating QObjects and graphics items. + + \tableofcontents + + \section1 The Animation Architecture + + We will in this section take a high-level look at the animation + framework's architecture and how it is used to animate Qt + properties. The following diagram shows the most important classes + in the animation framework. + + \image animations-architecture.png + + The animation framework foundation consists of the base class + QAbstractAnimation, and its two subclasses QVariantAnimation and + QAnimationGroup. QAbstractAnimation is the ancestor of all + animations. It represents basic properties that are common for all + animations in the framework; notably, the ability to start, stop, + and pause an animation. It is also receives the time change + notifications. + + The animation framework further provides the QPropertyAnimation + class, which inherits QVariantAnimation and performs animation of + a Qt property, which is part of Qt's \l{Meta-Object + System}{meta-object system}. The class performs an interpolation + over the property using an easing curve. So when you want to + animate a value, you can declare it as a property and make your + class a QObject. Note that this gives us great freedom in + animating already existing widgets and other \l{QObject}s. + + Complex animations can be constructed by building a tree structure + of \l{QAbstractAnimation}s. The tree is built by using + \l{QAnimationGroup}s, which function as containers for other + animations. Note also that the groups are subclasses of + QAbstractAnimation, so groups can themselves contain other groups. + + The animation framework can be used on its own, but is also + designed to be part of the state machine framework (See the + \l{The State Machine Framework}{state machine framework} for an + introduction to the Qt state machine). The state machine provides + a special state that can play an animation. A QState can also set + properties when the state is entered or exited, and this special + animation state will interpolate between these values when given a + QPropertyAnimation. We will look more closely at this later. + + Behind the scenes, the animations are controlled by a global + timer, which sends \l{QAbstractAnimation::updateCurrentTime()}{updates} to + all animations that are playing. + + For detailed descriptions of the classes' function and roles in + the framework, please look up their class descriptions. + + \section1 Animating Qt Properties + + As mentioned in the previous section, the QPropertyAnimation class + can interpolate over Qt properties. It is this class that should + be used for animation of values; in fact, its superclass, + QVariantAnimation, is an abstract class, and cannot be used + directly. + + A major reason we chose to animate Qt properties is that it + presents us with freedom to animate already existing classes in + the Qt API. Notably, the QWidget class (which we can also embed in + a QGraphicsView) has properties for its bounds, colors, etc. + Let's look at a small example: + + \code + QPushButton button("Animated Button"); + button.show(); + + QPropertyAnimation animation(&button, "geometry"); + animation.setDuration(10000); + animation.setStartValue(QRect(0, 0, 100, 30)); + animation.setEndValue(QRect(250, 250, 100, 30)); + + animation.start(); + \endcode + + This code will move \c button from the top left corner of the + screen to the position (250, 250) in 10 seconds (10000 milliseconds). + + The example above will do a linear interpolation between the + start and end value. It is also possible to set values + situated between the start and end value. The interpolation + will then go by these points. + + \code + QPushButton button("Animated Button"); + button.show(); + + QPropertyAnimation animation(&button, "geometry"); + animation.setDuration(10000); + + animation.setKeyValueAt(0, QRect(0, 0, 100, 30)); + animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30)); + animation.setKeyValueAt(1, QRect(0, 0, 100, 30)); + + animation.start(); + \endcode + + In this example, the animation will take the button to (250, 250) + in 8 seconds, and then move it back to its original position in + the remaining 2 seconds. The movement will be linearly + interpolated between these points. + + You also have the possibility to animate values of a QObject + that is not declared as a Qt property. The only requirement is + that this value has a setter. You can then subclass the class + containing the value and declare a property that uses this setter. + Note that each Qt property requires a getter, so you will need to + provide a getter yourself if this is not defined. + + \code + class MyGraphicsRectItem : public QObject, public QGraphicsRectItem + { + Q_OBJECT + Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) + }; + \endcode + + In the above code example, we subclass QGraphicsRectItem and + define a geometry property. We can now animate the widgets + geometry even if QGraphicsRectItem does not provide the geometry + property. + + For a general introduction to the Qt property system, see its + \l{Qt's Property System}{overview}. + + \section1 Animations and the Graphics View Framework + + When you want to animate \l{QGraphicsItem}s, you also use + QPropertyAnimation. However, QGraphicsItem does not inherit QObject. + A good solution is to subclass the graphics item you wish to animate. + This class will then also inherit QObject. + This way, QPropertyAnimation can be used for \l{QGraphicsItem}s. + The example below shows how this is done. Another possibility is + to inherit QGraphicsWidget, which already is a QObject. + + \code + class Pixmap : public QObject, public QGraphicsPixmapItem + { + Q_OBJECT + Q_PROPERTY(QPointF pos READ pos WRITE setPos) + ... + \endcode + + As described in the previous section, we need to define + properties that we wish to animate. + + Note that QObject must be the first class inherited as the + meta-object system demands this. + + \warning The QItemAnimation class, which was initially intended + for animating \l{QGraphicsItem}s may be deprecated or removed from + the animation framework. + + \omit (need something about the list of animations). \endomit + + \section1 Easing Curves + + As mentioned, QPropertyAnimation performs an interpolation between + the start and end property value. In addition to adding more key + values to the animation, you can also use an easing curve. Easing + curves describe a function that controls how the speed of the + interpolation between 0 and 1 should be, and are useful if you + want to control the speed of an animation without changing the + path of the interpolation. + + \code + QPushButton button("Animated Button"); + button.show(); + + QPropertyAnimation animation(&button, "geometry"); + animation.setDuration(3000); + animation.setStartValue(QRect(0, 0, 100, 30)); + animation.setEndValue(QRect(250, 250, 100, 30)); + + animation.setEasingCurve(QEasingCurve::OutBounce); + + animation.start(); + \endcode + + Here the animation will follow a curve that makes it bounce like a + ball as if it was dropped from the start to the end position. + QEasingCurve has a large collection of curves for you to choose + from. These are defined by the QEasingCurve::Type enum. If you are + in need of another curve, you can also implement one yourself, and + register it with QEasingCurve. + + \omit Drop this for the first Lab release + (Example of custom easing curve (without the actual impl of + the function I expect) + \endomit + + \section1 Putting Animations Together + + An application will often contain more than one animation. For + instance, you might want to move more than one graphics item + simultaneously or move them in sequence after each other. + + The subclasses of QAnimationGroup (QSequentialAnimationGroup and + QParallelAnimationGroup) are containers for other animations so + that these animations can be animated either in sequence or + parallel. The QAnimationGroup is an example of an animation that + does not animate properties, but it gets notified of time changes + periodically. This enables it to forward those time changes to its + contained animations, and thereby controlling when its animations + are played. + + Let's look at code examples that use both + QSequentialAnimationGroup and QParallelAnimationGroup, starting + off with the latter. + + \code + QPushButton *bonnie = new QPushButton("Bonnie"); + bonnie->show(); + + QPushButton *clyde = new QPushButton("Clyde"); + clyde->show(); + + QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry"); + // Set up anim1 + + QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry"); + // Set up anim2 + + QParallelAnimationGroup *group = new QParallelAnimationGroup; + group->addAnimation(anim1); + group->addAnimation(anim2); + + group->start(); + \endcode + + A parallel group plays more than one animation at the same time. + Calling its \l{QAbstractAnimation::}{start()} function will start + all animations it governs. + + \code + QPushButton button("Animated Button"); + button.show(); + + QPropertyAnimation anim1(&button, "geometry"); + anim1.setDuration(3000); + anim1.setStartValue(QRect(0, 0, 100, 30)); + anim1.setEndValue(QRect(500, 500, 100, 30)); + + QPropertyAnimation anim2(&button, "geometry"); + anim2.setDuration(3000); + anim2.setStartValue(QRect(500, 500, 100, 30)); + anim2.setEndValue(QRect(1000, 500, 100, 30)); + + QSequentialAnimationGroup group; + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + + group.start(); + \endcode + + As you no doubt have guessed, QSequentialAnimationGroup plays + its animations in sequence. It starts the next animation in + the list after the previous is finished. + + Since an animation group is an animation itself, you can add + it to another group. This way, you can build a tree structure + of animations which specifies when the animations are played + in relation to each other. + + \section1 Animations and States + + When using a \l{The State Machine Framework}{state machine}, we + have a special state, QAnimationState, that will play one or more + animations. + + The QState::addAnimatedTransition() convenience function lets you + associate an animation to a state transition. The function will + create the QAnimationState for you, and insert it into the state + machine. We also have the possibility to associate properties with + the states rather than setting the start and end values ourselves. + Below is a complete code example that animates the geometry of a + QPushButton. + + \code + QPushButton *button = new QPushButton("Animated Button"); + button->show(); + + QStateMachine *machine = new QStateMachine; + + QState *state1 = new QState(machine->rootState()); + state1->setPropertyOnEntry(button, "geometry", + QRect(0, 0, 100, 30)); + machine->setInitialState(state1); + + QState *state2 = new QState(machine->rootState()); + state2->setPropertyOnEntry(button, "geometry", + QRect(250, 250, 100, 30)); + + state1->addAnimatedTransition(button, SIGNAL(clicked()), state2, + new QPropertyAnimation(button, "geometry")); + state2->addAnimatedTransition(button, SIGNAL(clicked()), state1, + new QPropertyAnimation(button, "geometry")); + + machine->start(); + \endcode + + For a more comprehensive example of how to use the state machine + framework for animations, see the states example (it lives in the + \c{examples/animation/states} directory). +*/ + diff --git a/doc/src/diagrams/animations-architecture.svg b/doc/src/diagrams/animations-architecture.svg new file mode 100644 index 0000000..0246510 --- /dev/null +++ b/doc/src/diagrams/animations-architecture.svg @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + QAbstractAnimation + + QVariantAnimation + + QAnimationGroup + + + + QPropertyAnimation + + + QSequentialAnimationGroup + + QParallelAnimationGroup + + + + diff --git a/doc/src/diagrams/programs/easingcurve/easingcurve.pro b/doc/src/diagrams/programs/easingcurve/easingcurve.pro new file mode 100644 index 0000000..0b80127 --- /dev/null +++ b/doc/src/diagrams/programs/easingcurve/easingcurve.pro @@ -0,0 +1,13 @@ +###################################################################### +# Automatically generated by qmake (2.01a) fr 13. feb 13:26:38 2009 +###################################################################### + +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp + +CONFIG += console \ No newline at end of file diff --git a/doc/src/diagrams/programs/easingcurve/main.cpp b/doc/src/diagrams/programs/easingcurve/main.cpp new file mode 100644 index 0000000..98e9d37 --- /dev/null +++ b/doc/src/diagrams/programs/easingcurve/main.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include + +void createCurveIcons(); + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + createCurveIcons(); + return app.exit(); +} + +void createCurveIcons() +{ + QDir dir(QDir::current()); + if (dir.dirName() == QLatin1String("debug") || dir.dirName() == QLatin1String("release")) { + dir.cdUp(); + } + dir.cdUp(); + dir.cdUp(); + dir.cdUp(); + QSize iconSize(128, 128); + QPixmap pix(iconSize); + QPainter painter(&pix); + QLinearGradient gradient(0,0, 0, iconSize.height()); + gradient.setColorAt(0.0, QColor(240, 240, 240)); + gradient.setColorAt(1.0, QColor(224, 224, 224)); + QBrush brush(gradient); + const QMetaObject &mo = QEasingCurve::staticMetaObject; + QMetaEnum metaEnum = mo.enumerator(mo.indexOfEnumerator("Type")); + QFont oldFont = painter.font(); + // Skip QEasingCurve::Custom + QString output(QString::fromAscii("%1/images").arg(dir.absolutePath())); + printf("Generating images to %s\n", qPrintable(output)); + for (int i = 0; i < QEasingCurve::NCurveTypes - 1; ++i) { + painter.setFont(oldFont); + QString name(QLatin1String(metaEnum.key(i))); + painter.fillRect(QRect(QPoint(0, 0), iconSize), brush); + QEasingCurve curve((QEasingCurve::Type)i); + painter.setPen(QColor(0, 0, 255, 64)); + qreal xAxis = iconSize.height()/1.5; + qreal yAxis = iconSize.width()/3; + painter.drawLine(0, xAxis, iconSize.width(), xAxis); // hor + painter.drawLine(yAxis, 0, yAxis, iconSize.height()); // ver + + qreal curveScale = iconSize.height()/2; + + painter.drawLine(yAxis - 2, xAxis - curveScale, yAxis + 2, xAxis - curveScale); // hor + painter.drawLine(yAxis + curveScale, xAxis + 2, yAxis + curveScale, xAxis - 2); // ver + painter.drawText(yAxis + curveScale - 8, xAxis - curveScale - 4, QLatin1String("(1,1)")); + + painter.drawText(yAxis + 42, xAxis + 10, QLatin1String("progress")); + painter.drawText(15, xAxis - curveScale - 10, QLatin1String("ease")); + + painter.setPen(QPen(Qt::red, 1, Qt::DotLine)); + painter.drawLine(yAxis, xAxis - curveScale, yAxis + curveScale, xAxis - curveScale); // hor + painter.drawLine(yAxis + curveScale, xAxis, yAxis + curveScale, xAxis - curveScale); // ver + + QPoint currentPos(yAxis, xAxis); + + painter.setPen(Qt::black); + QFont font = oldFont; + font.setPixelSize(oldFont.pixelSize() + 15); + painter.setFont(font); + painter.drawText(0, iconSize.height() - 20, iconSize.width(), 20, Qt::AlignHCenter, name); + + for (qreal t = 0; t < 1.0; t+=1.0/curveScale) { + QPoint to; + to.setX(yAxis + curveScale * t); + to.setY(xAxis - curveScale * curve.valueForProgress(t)); + painter.drawLine(currentPos, to); + currentPos = to; + } + QString fileName(QString::fromAscii("qeasingcurve-%1.png").arg(name.toLower())); + printf("%s\n", qPrintable(fileName)); + pix.save(QString::fromAscii("%1/%2").arg(output).arg(fileName), "PNG"); + } +} + + diff --git a/doc/src/examples-overview.qdoc b/doc/src/examples-overview.qdoc index 549574d..92ccd4e 100644 --- a/doc/src/examples-overview.qdoc +++ b/doc/src/examples-overview.qdoc @@ -319,6 +319,14 @@ from displaying Web pages within a Qt user interface to an implementation of a basic function Web browser. + \section1 \l{Qt Examples#State Machine}{State Machine} + + Qt provides a powerful hierchical finite state machine through the Qt State + Machine classes. + + These examples demonstrate the fundamental aspects of implementing + Statecharts with Qt. + \section1 \l{Qt Examples#Qt for Embedded Linux}{Qt for Embedded Linux} \l{Qt Examples#Qt for Embedded Linux}{\inlineimage qt-embedded-examples.png diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc index 29c6c0b..c55d29f 100644 --- a/doc/src/examples.qdoc +++ b/doc/src/examples.qdoc @@ -86,6 +86,12 @@ \o \l{activeqt/webbrowser}{Web Browser}\raisedaster \o \l{activeqt/wrapper}{Wrapper}\raisedaster \endlist + + \section1 Animation + + \list + \o \l{animation/stickman}{Stick man}\raisedaster + \endlist \section1 Concurrent Programming @@ -308,6 +314,17 @@ \o \l{sql/sqlwidgetmapper}{SQL Widget Mapper}\raisedaster \endlist + \section1 State Machine + + \list + \o \l{statemachine/eventtransitions}{Event Transitions}\raisedaster + \o \l{statemachine/factorial}{Factorial States}\raisedaster + \o \l{statemachine/pingpong}{Ping Pong States}\raisedaster + \o \l{statemachine/trafficlight}{Traffic Light}\raisedaster + \o \l{statemachine/twowaybutton}{Two-way Button}\raisedaster + \o \l{statemachine/tankgame}{Tank Game}\raisedaster + \endlist + \section1 Threads \list diff --git a/doc/src/examples/eventtransitions.qdoc b/doc/src/examples/eventtransitions.qdoc new file mode 100644 index 0000000..3b956bb --- /dev/null +++ b/doc/src/examples/eventtransitions.qdoc @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example statemachine/eventtransitions + \title Event Transitions Example + + The Event Transitions example shows how to use event transitions, a + feature of \l{The State Machine Framework}. + + \snippet examples/statemachine/eventtransitions/main.cpp 0 + + The \c Window class's constructors begins by creating a button. + + \snippet examples/statemachine/eventtransitions/main.cpp 1 + + Two states, \c s1 and \c s2, are created; upon entry they will assign + "Outside" and "Inside" to the button's text, respectively. + + \snippet examples/statemachine/eventtransitions/main.cpp 2 + + When the button receives an event of type QEvent::Enter and the state + machine is in state \c s1, the machine will transition to state \c s2. + + \snippet examples/statemachine/eventtransitions/main.cpp 3 + + When the button receives an event of type QEvent::Leave and the state + machine is in state \c s2, the machine will transition back to state \c + s1. + + \snippet examples/statemachine/eventtransitions/main.cpp 4 + + Next, the state \c s3 is created. \c s3 will be entered when the button + receives an event of type QEvent::MouseButtonPress and the state machine + is in state \c s2. When the button receives an event of type + QEvent::MouseButtonRelease and the state machine is in state \c s3, the + machine will transition back to state \c s2. + + \snippet examples/statemachine/eventtransitions/main.cpp 5 + + Finally, the states are added to the machine as top-level states, the + initial state is set to be \c s1 ("Outside"), and the machine is started. + + \snippet examples/statemachine/eventtransitions/main.cpp 6 + + The main() function constructs a Window object and shows it. + +*/ diff --git a/doc/src/examples/factorial.qdoc b/doc/src/examples/factorial.qdoc new file mode 100644 index 0000000..2a72e0a --- /dev/null +++ b/doc/src/examples/factorial.qdoc @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example statemachine/factorial + \title Factorial States Example + + The Factorial States example shows how to use \l{The State Machine + Framework} to calculate the factorial of an integer. + + The statechart for calculating the factorial looks as follows: + + \img factorial-example.png + \omit + \caption This is a caption + \endomit + + In other words, the state machine calculates the factorial of 6 and prints + the result. + + \snippet examples/statemachine/factorial/main.cpp 0 + + The Factorial class is used to hold the data of the computation, \c x and + \c fac. It also provides a signal that's emitted whenever the value of \c + x changes. + + \snippet examples/statemachine/factorial/main.cpp 1 + + The FactorialLoopTransition class implements the guard (\c x > 1) and + calculations (\c fac = \c x * \c fac; \c x = \c x - 1) of the factorial + loop. + + \snippet examples/statemachine/factorial/main.cpp 2 + + The FactorialDoneTransition class implements the guard (\c x <= 1) that + terminates the factorial computation. It also prints the final result to + standard output. + + \snippet examples/statemachine/factorial/main.cpp 3 + + The application's main() function first creates the application object, a + Factorial object and a state machine. + + \snippet examples/statemachine/factorial/main.cpp 4 + + The \c compute state is created, and the initial values of \c x and \c fac + are defined. A FactorialLoopTransition object is created and added to the + state. + + \snippet examples/statemachine/factorial/main.cpp 5 + + A final state, \c done, is created, and a FactorialDoneTransition object + is created with \c done as its target state. The transition is then added + to the \c compute state. + + \snippet examples/statemachine/factorial/main.cpp 6 + + The machine's initial state is set to be the \c compute state. We connect + the QStateMachine::finished() signal to the QCoreApplication::quit() slot, + so the application will quit when the state machine's work is + done. Finally, the state machine is started, and the application's event + loop is entered. + + */ diff --git a/doc/src/examples/pingpong.qdoc b/doc/src/examples/pingpong.qdoc new file mode 100644 index 0000000..040e429 --- /dev/null +++ b/doc/src/examples/pingpong.qdoc @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example statemachine/pingpong + \title Ping Pong States Example + + The Ping Pong States example shows how to use parallel states together + with custom events and transitions in \l{The State Machine Framework}. + + This example implements a statechart where two states communicate by + posting events to the state machine. The state chart looks as follows: + + \img pingpong-example.png + \omit + \caption This is a caption + \endomit + + The \c pinger and \c ponger states are parallel states, i.e. they are + entered simultaneously and will take transitions independently of + eachother. + + The \c pinger state will post the first \c ping event upon entry; the \c + ponger state will respond by posting a \c pong event; this will cause the + \c pinger state to post a new \c ping event; and so on. + + \snippet examples/statemachine/pingpong/main.cpp 0 + + Two custom events are defined, \c PingEvent and \c PongEvent. + + \snippet examples/statemachine/pingpong/main.cpp 1 + + The \c Pinger class defines a state that posts a \c PingEvent to the state + machine when the state is entered. + + \snippet examples/statemachine/pingpong/main.cpp 2 + + The \c PingTransition class defines a transition that is triggered by + events of type \c PingEvent, and that posts a \c PongEvent (with a delay + of 500 milliseconds) to the state machine when the transition is + triggered. + + \snippet examples/statemachine/pingpong/main.cpp 3 + + The \c PongTransition class defines a transition that is triggered by + events of type \c PongEvent, and that posts a \c PingEvent (with a delay + of 500 milliseconds) to the state machine when the transition is + triggered. + + \snippet examples/statemachine/pingpong/main.cpp 4 + + The main() function begins by creating a state machine and a parallel + state group. + + \snippet examples/statemachine/pingpong/main.cpp 5 + + Next, the \c pinger and \c ponger states are created, with the parallel + state group as their parent state. Note that the transitions are \e + targetless. When such a transition is triggered, the source state won't be + exited and re-entered; only the transition's onTransition() function will + be called, and the state machine's configuration will remain the same, + which is precisely what we want in this case. + + \snippet examples/statemachine/pingpong/main.cpp 6 + + Finally, the group is added to the state machine, the machine is started, + and the application event loop is entered. + + */ diff --git a/doc/src/examples/stickman.qdoc b/doc/src/examples/stickman.qdoc new file mode 100644 index 0000000..49f4953 --- /dev/null +++ b/doc/src/examples/stickman.qdoc @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example animation/stickman + \title Stickman Example + + The Stickman example shows how to animate transitions in a state machine to implement key frame + animations. + + \image stickman-example.png + + In this example, we will write a small application which animates the joints in a skeleton and + projects a stickman figure on top. The stickman can be either "alive" or "dead", and when in the + "alive" state, he can be performing different actions defined by key frame animations. + + Animations are implemented as composite states. Each child state of the animation state + represents a frame in the animation by setting the position of each joint in the stickman's + skeleton to the positions defined for the particular frame. The frames are then bound together + with animated transitions that trigger on the source state's polished() signal. Thus, the + machine will enter the state representing the next frame in the animation immediately after it + has finished animating into the previous frame. + + \image stickman-example1.png + + The states for an animation is constructed by reading a custom animation file format and + creating states that assign values to the the "position" properties of each of the nodes in the + skeleton graph. + + \snippet examples/animation/stickman/lifecycle.cpp 1 + + The states are then bound together with signal transitions that listen to the polished() signal. + + \snippet examples/animation/stickman/lifecycle.cpp 2 + + The last frame state is given a transition to the first one, so that the animation will loop + until it is interrupted when a transition out from the animation state is taken. To get smooth + animations between the different key frames, we set a default animation on the state machine. + This is a parallel animation group which contains animations for all the "position" properties + and will be selected by default when taking any transition that leads into a state that assigns + values to these properties. + + \snippet examples/animation/stickman/lifecycle.cpp 3 + + Several such animation states are constructed, and are placed together as children of a top + level "alive" state which represents the stickman life cycle. Transitions go from the parent + state to the child state to ensure that each of the child states inherit them. + + \image stickman-example2.png + + This saves us the effort of connect every state to every state with identical transitions. The + state machine makes sure that transitions between the key frame animations are also smooth by + applying the default animation when interrupting one and starting another. + + Finally, there is a transition out from the "alive" state and into the "dead" state. This is + a custom transition type called LightningSrikesTransition which samples every second and + triggers at random (one out of fifty times on average.) + + \snippet examples/animation/stickman/lifecycle.cpp 4 + + When it triggers, the machine will first enter a "lightningBlink" state which uses a timer to + pause for a brief period of time while the background color of the scene is white. This gives us + a flash effect when the lightning strikes. + + \snippet examples/animation/stickman/lifecycle.cpp 5 + + We start and stop a QTimer object when entering and exiting the state. Then we transition into + the "dead" state when the timer times out. + + \snippet examples/animation/stickman/lifecycle.cpp 0 + + When the machine is in the "dead" state, it will be unresponsive. This is because the "dead" + state has no transitions leading out. + + \image stickman-example3.png + +*/ diff --git a/doc/src/examples/tankgame.qdoc b/doc/src/examples/tankgame.qdoc new file mode 100644 index 0000000..ab3e0f4 --- /dev/null +++ b/doc/src/examples/tankgame.qdoc @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example statemachine/tankgame + \title Tank Game Example + + The Tank Game example is part of the in \l{The State Machine Framework}. It shows how to use + parallel states to implement artificial intelligence controllers that run in parallel, and error + states to handle run-time errors in parts of the state graph created by external plugins. + + \image tankgame-example.png + + In this example we write a simple game. The application runs a state machine with two main + states: A "stopped" state and a "running" state. The user can load plugins from the disk by + selecting the "Add tank" menu item. + + When the "Add tank" menu item is selected, the "plugins" subdirectory in the example's + directory is searched for compatible plugins. If any are found, they will be listed in a + dialog box created using QInputDialog::getItem(). + + \snippet examples/statemachine/tankgame/mainwindow.cpp 1 + + If the user selects a plugin, the application will construct a TankItem object, which inherits + from QGraphicsItem and QObject, and which implements an agreed-upon interface using the + meta-object mechanism. + + \snippet examples/statemachine/tankgame/tankitem.h 0 + + The tank item will be passed to the plugin's create() function. This will in turn return a + QState object which is expected to implement an artificial intelligence which controls the + tank and attempts to destroy other tanks it detects. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 2 + + Each returned QState object becomes a descendant of a \c region in the "running" state, which is + defined as a parallel state. This means that entering the "running" state will cause each of the + plugged-in QState objects to be entered simultaneously, allowing the tanks to run independently + of each other. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 0 + + The maximum number of tanks on the map is four, and when this number is reached, the + "Add tank" menu item should be disabled. This is implemented by giving the "stopped" state two + children which define whether the map is full or not. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 5 + + To make sure that we go into the correct child state when returning from the "running" state + (if the "Stop game" menu item is selected while the game is running) we also give the "stopped" + state a history state which we make the initial state of "stopped" state. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 3 + + Since part of the state graph is defined by external plugins, we have no way of controlling + whether they contain errors. By default, run-time errors are handled in the state machine by + entering a top level state which prints out an error message and never exits. If we were to + use this default behavior, a run-time error in any of the plugins would cause the "running" + state to exit, and thus all the other tanks to stop running as well. A better solution would + be if the broken plugin was disabled and the rest of the tanks allowed to continue as before. + + This is done by setting the error state of the plugin's top-most state to a special error state + defined specifically for the plugin in question. + + \snippet examples/statemachine/tankgame/mainwindow.cpp 4 + + If a run-time error occurs in \c pluginState or any of its descendants, the state machine will + search the hierarchy of ancestors until it finds a state whose error state is different from + \c null. (Note that if we are worried that a plugin could inadvertedly be overriding our + error state, we could search the descendants of \c pluginState and verify that their error + states are set to \c null before accepting the plugin.) + + The specialized \c errorState sets the "enabled" property of the tank item in question to false, + causing it to be painted with a red cross over it to indicate that it is no longer running. + Since the error state is a child of the same region in the parallel "running" state as + \c pluginState, it will not exit the "running" state, and the other tanks will continue running + without disruption. + +*/ diff --git a/doc/src/examples/trafficlight.qdoc b/doc/src/examples/trafficlight.qdoc new file mode 100644 index 0000000..ae62127 --- /dev/null +++ b/doc/src/examples/trafficlight.qdoc @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example statemachine/trafficlight + \title Traffic Light Example + + The Traffic Light example shows how to use \l{The State Machine Framework} + to implement the control flow of a traffic light. + + \image trafficlight-example.png + + In this example we write a TrafficLightWidget class. The traffic light has + three lights: Red, yellow and green. The traffic light transitions from + one light to another (red to yellow to green to yellow to red again) at + certain intervals. + + \snippet examples/statemachine/trafficlight/main.cpp 0 + + The LightWidget class represents a single light of the traffic light. It + provides an \c on property and two slots, turnOn() and turnOff(), to turn + the light on and off, respectively. The widget paints itself in the color + that's passed to the constructor. + + \snippet examples/statemachine/trafficlight/main.cpp 1 + + The TrafficLightWidget class represents the visual part of the traffic + light; it's a widget that contains three lights arranged vertically, and + provides accessor functions for these. + + \snippet examples/statemachine/trafficlight/main.cpp 2 + + The createLightState() function creates a state that turns a light on when + the state is entered, and off when the state is exited. The state uses a + timer, and as we shall see the timeout is used to transition from one + LightState to another. Here is the statechart for the light state: + + \img trafficlight-example1.png + \omit + \caption This is a caption + \endomit + + \snippet examples/statemachine/trafficlight/main.cpp 3 + + The TrafficLight class combines the TrafficLightWidget with a state + machine. The state graph has four states: red-to-yellow, yellow-to-green, + green-to-yellow and yellow-to-red. The initial state is red-to-yellow; + when the state's timer times out, the state machine transitions to + yellow-to-green. The same process repeats through the other states. + This is what the statechart looks like: + + \img trafficlight-example2.png + \omit + \caption This is a caption + \endomit + + \snippet examples/statemachine/trafficlight/main.cpp 4 + + The main() function constructs a TrafficLight and shows it. + +*/ diff --git a/doc/src/examples/twowaybutton.qdoc b/doc/src/examples/twowaybutton.qdoc new file mode 100644 index 0000000..87de2e8 --- /dev/null +++ b/doc/src/examples/twowaybutton.qdoc @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example statemachine/twowaybutton + \title Two-way Button Example + + The Two-way button example shows how to use \l{The State Machine + Framework} to implement a simple state machine that toggles the current + state when a button is clicked. + + \snippet examples/statemachine/twowaybutton/main.cpp 0 + + The application's main() function begins by constructing the application + object, a button and a state machine. + + \snippet examples/statemachine/twowaybutton/main.cpp 1 + + The state machine has two states; \c on and \c off. When either state is + entered, the text of the button will be set accordingly. + + \snippet examples/statemachine/twowaybutton/main.cpp 2 + + When the state machine is in the \c off state and the button is clicked, + it will transition to the \c on state; when the state machine is in the \c + on state and the button is clicked, it will transition to the \c off + state. + + \snippet examples/statemachine/twowaybutton/main.cpp 3 + + The states are added to the state machine; they become top-level (sibling) + states. + + \snippet examples/statemachine/twowaybutton/main.cpp 4 + + The initial state is \c off; this is the state the state machine will + immediately transition to once the state machine is started. + + \snippet examples/statemachine/twowaybutton/main.cpp 5 + + Finally, the button is resized and made visible, and the application event + loop is entered. + +*/ diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc index f48c3d7..3bfb5af 100644 --- a/doc/src/external-resources.qdoc +++ b/doc/src/external-resources.qdoc @@ -334,6 +334,16 @@ */ /*! + \externalpage http://www.w3.org/TR/scxml/ + \title State Chart XML: State Machine Notation for Control Abstraction +*/ + +/*! + \externalpage http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Statecharts.pdf + \title Statecharts: A visual formalism for complex systems +*/ + +/*! \externalpage http://www.gnu.org/licenses/gpl.html \title GNU General Public License */ diff --git a/doc/src/groups.qdoc b/doc/src/groups.qdoc index c9cedc4..3c4da53 100644 --- a/doc/src/groups.qdoc +++ b/doc/src/groups.qdoc @@ -69,6 +69,18 @@ */ /*! + \group animation + \ingroup groups + + \title Animation Framework + \brief Classes for animations, states and transitions. + + These classes provide a framework for creating both simple and complex + animations. \l{The Animation Framework} also provides states and animated + transitions, making it easy to create animated stateful forms. +*/ + +/*! \group abstractwidgets \title Abstract Widget Classes \ingroup groups @@ -597,3 +609,14 @@ These classes are relevant to developers who are working with Qt Script's debugging features. */ + +/*! + \group statemachine + \ingroup groups + + \title State Machine Classes + \brief Classes for constructing and executing state graphs. + + These classes are provided by \l{The State Machine Framework} for creating + event-driven state machines. +*/ diff --git a/doc/src/images/animations-architecture.png b/doc/src/images/animations-architecture.png new file mode 100644 index 0000000..9b581af Binary files /dev/null and b/doc/src/images/animations-architecture.png differ diff --git a/doc/src/images/factorial-example.png b/doc/src/images/factorial-example.png new file mode 100644 index 0000000..8fb1cc6 Binary files /dev/null and b/doc/src/images/factorial-example.png differ diff --git a/doc/src/images/pingpong-example.png b/doc/src/images/pingpong-example.png new file mode 100644 index 0000000..af707e4 Binary files /dev/null and b/doc/src/images/pingpong-example.png differ diff --git a/doc/src/images/qeasingcurve-cosinecurve.png b/doc/src/images/qeasingcurve-cosinecurve.png new file mode 100644 index 0000000..b27e763 Binary files /dev/null and b/doc/src/images/qeasingcurve-cosinecurve.png differ diff --git a/doc/src/images/qeasingcurve-inback.png b/doc/src/images/qeasingcurve-inback.png new file mode 100644 index 0000000..8506c0f Binary files /dev/null and b/doc/src/images/qeasingcurve-inback.png differ diff --git a/doc/src/images/qeasingcurve-inbounce.png b/doc/src/images/qeasingcurve-inbounce.png new file mode 100644 index 0000000..275b38c Binary files /dev/null and b/doc/src/images/qeasingcurve-inbounce.png differ diff --git a/doc/src/images/qeasingcurve-incirc.png b/doc/src/images/qeasingcurve-incirc.png new file mode 100644 index 0000000..b985e9c Binary files /dev/null and b/doc/src/images/qeasingcurve-incirc.png differ diff --git a/doc/src/images/qeasingcurve-incubic.png b/doc/src/images/qeasingcurve-incubic.png new file mode 100644 index 0000000..e417ee1 Binary files /dev/null and b/doc/src/images/qeasingcurve-incubic.png differ diff --git a/doc/src/images/qeasingcurve-incurve.png b/doc/src/images/qeasingcurve-incurve.png new file mode 100644 index 0000000..d9a9340 Binary files /dev/null and b/doc/src/images/qeasingcurve-incurve.png differ diff --git a/doc/src/images/qeasingcurve-inelastic.png b/doc/src/images/qeasingcurve-inelastic.png new file mode 100644 index 0000000..b242fd3 Binary files /dev/null and b/doc/src/images/qeasingcurve-inelastic.png differ diff --git a/doc/src/images/qeasingcurve-inexpo.png b/doc/src/images/qeasingcurve-inexpo.png new file mode 100644 index 0000000..f06316c Binary files /dev/null and b/doc/src/images/qeasingcurve-inexpo.png differ diff --git a/doc/src/images/qeasingcurve-inoutback.png b/doc/src/images/qeasingcurve-inoutback.png new file mode 100644 index 0000000..9fd1446 Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutback.png differ diff --git a/doc/src/images/qeasingcurve-inoutbounce.png b/doc/src/images/qeasingcurve-inoutbounce.png new file mode 100644 index 0000000..fb65f31 Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutbounce.png differ diff --git a/doc/src/images/qeasingcurve-inoutcirc.png b/doc/src/images/qeasingcurve-inoutcirc.png new file mode 100644 index 0000000..123cc54 Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutcirc.png differ diff --git a/doc/src/images/qeasingcurve-inoutcubic.png b/doc/src/images/qeasingcurve-inoutcubic.png new file mode 100644 index 0000000..b07695c Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutcubic.png differ diff --git a/doc/src/images/qeasingcurve-inoutelastic.png b/doc/src/images/qeasingcurve-inoutelastic.png new file mode 100644 index 0000000..65851e1 Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutelastic.png differ diff --git a/doc/src/images/qeasingcurve-inoutexpo.png b/doc/src/images/qeasingcurve-inoutexpo.png new file mode 100644 index 0000000..7cbfb13 Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutexpo.png differ diff --git a/doc/src/images/qeasingcurve-inoutquad.png b/doc/src/images/qeasingcurve-inoutquad.png new file mode 100644 index 0000000..c5eed06 Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutquad.png differ diff --git a/doc/src/images/qeasingcurve-inoutquart.png b/doc/src/images/qeasingcurve-inoutquart.png new file mode 100644 index 0000000..3b66c0d Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutquart.png differ diff --git a/doc/src/images/qeasingcurve-inoutquint.png b/doc/src/images/qeasingcurve-inoutquint.png new file mode 100644 index 0000000..c74efe9 Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutquint.png differ diff --git a/doc/src/images/qeasingcurve-inoutsine.png b/doc/src/images/qeasingcurve-inoutsine.png new file mode 100644 index 0000000..5964f31 Binary files /dev/null and b/doc/src/images/qeasingcurve-inoutsine.png differ diff --git a/doc/src/images/qeasingcurve-inquad.png b/doc/src/images/qeasingcurve-inquad.png new file mode 100644 index 0000000..3373310 Binary files /dev/null and b/doc/src/images/qeasingcurve-inquad.png differ diff --git a/doc/src/images/qeasingcurve-inquart.png b/doc/src/images/qeasingcurve-inquart.png new file mode 100644 index 0000000..28086d8 Binary files /dev/null and b/doc/src/images/qeasingcurve-inquart.png differ diff --git a/doc/src/images/qeasingcurve-inquint.png b/doc/src/images/qeasingcurve-inquint.png new file mode 100644 index 0000000..330aa85 Binary files /dev/null and b/doc/src/images/qeasingcurve-inquint.png differ diff --git a/doc/src/images/qeasingcurve-insine.png b/doc/src/images/qeasingcurve-insine.png new file mode 100644 index 0000000..63d9238 Binary files /dev/null and b/doc/src/images/qeasingcurve-insine.png differ diff --git a/doc/src/images/qeasingcurve-linear.png b/doc/src/images/qeasingcurve-linear.png new file mode 100644 index 0000000..2a05885 Binary files /dev/null and b/doc/src/images/qeasingcurve-linear.png differ diff --git a/doc/src/images/qeasingcurve-outback.png b/doc/src/images/qeasingcurve-outback.png new file mode 100644 index 0000000..7cb34c6 Binary files /dev/null and b/doc/src/images/qeasingcurve-outback.png differ diff --git a/doc/src/images/qeasingcurve-outbounce.png b/doc/src/images/qeasingcurve-outbounce.png new file mode 100644 index 0000000..932fc16 Binary files /dev/null and b/doc/src/images/qeasingcurve-outbounce.png differ diff --git a/doc/src/images/qeasingcurve-outcirc.png b/doc/src/images/qeasingcurve-outcirc.png new file mode 100644 index 0000000..a1a6cb6 Binary files /dev/null and b/doc/src/images/qeasingcurve-outcirc.png differ diff --git a/doc/src/images/qeasingcurve-outcubic.png b/doc/src/images/qeasingcurve-outcubic.png new file mode 100644 index 0000000..aa1d604 Binary files /dev/null and b/doc/src/images/qeasingcurve-outcubic.png differ diff --git a/doc/src/images/qeasingcurve-outcurve.png b/doc/src/images/qeasingcurve-outcurve.png new file mode 100644 index 0000000..a949ae4 Binary files /dev/null and b/doc/src/images/qeasingcurve-outcurve.png differ diff --git a/doc/src/images/qeasingcurve-outelastic.png b/doc/src/images/qeasingcurve-outelastic.png new file mode 100644 index 0000000..2a9ba39 Binary files /dev/null and b/doc/src/images/qeasingcurve-outelastic.png differ diff --git a/doc/src/images/qeasingcurve-outexpo.png b/doc/src/images/qeasingcurve-outexpo.png new file mode 100644 index 0000000..e771c2e Binary files /dev/null and b/doc/src/images/qeasingcurve-outexpo.png differ diff --git a/doc/src/images/qeasingcurve-outinback.png b/doc/src/images/qeasingcurve-outinback.png new file mode 100644 index 0000000..7523727 Binary files /dev/null and b/doc/src/images/qeasingcurve-outinback.png differ diff --git a/doc/src/images/qeasingcurve-outinbounce.png b/doc/src/images/qeasingcurve-outinbounce.png new file mode 100644 index 0000000..ab73d02 Binary files /dev/null and b/doc/src/images/qeasingcurve-outinbounce.png differ diff --git a/doc/src/images/qeasingcurve-outincirc.png b/doc/src/images/qeasingcurve-outincirc.png new file mode 100644 index 0000000..ec4b8d3 Binary files /dev/null and b/doc/src/images/qeasingcurve-outincirc.png differ diff --git a/doc/src/images/qeasingcurve-outincubic.png b/doc/src/images/qeasingcurve-outincubic.png new file mode 100644 index 0000000..8b8ae68 Binary files /dev/null and b/doc/src/images/qeasingcurve-outincubic.png differ diff --git a/doc/src/images/qeasingcurve-outinelastic.png b/doc/src/images/qeasingcurve-outinelastic.png new file mode 100644 index 0000000..89dde2c Binary files /dev/null and b/doc/src/images/qeasingcurve-outinelastic.png differ diff --git a/doc/src/images/qeasingcurve-outinexpo.png b/doc/src/images/qeasingcurve-outinexpo.png new file mode 100644 index 0000000..5909901 Binary files /dev/null and b/doc/src/images/qeasingcurve-outinexpo.png differ diff --git a/doc/src/images/qeasingcurve-outinquad.png b/doc/src/images/qeasingcurve-outinquad.png new file mode 100644 index 0000000..7ddefee Binary files /dev/null and b/doc/src/images/qeasingcurve-outinquad.png differ diff --git a/doc/src/images/qeasingcurve-outinquart.png b/doc/src/images/qeasingcurve-outinquart.png new file mode 100644 index 0000000..00ef597 Binary files /dev/null and b/doc/src/images/qeasingcurve-outinquart.png differ diff --git a/doc/src/images/qeasingcurve-outinquint.png b/doc/src/images/qeasingcurve-outinquint.png new file mode 100644 index 0000000..361bfaa4 Binary files /dev/null and b/doc/src/images/qeasingcurve-outinquint.png differ diff --git a/doc/src/images/qeasingcurve-outinsine.png b/doc/src/images/qeasingcurve-outinsine.png new file mode 100644 index 0000000..1737041 Binary files /dev/null and b/doc/src/images/qeasingcurve-outinsine.png differ diff --git a/doc/src/images/qeasingcurve-outquad.png b/doc/src/images/qeasingcurve-outquad.png new file mode 100644 index 0000000..6f27cbd Binary files /dev/null and b/doc/src/images/qeasingcurve-outquad.png differ diff --git a/doc/src/images/qeasingcurve-outquart.png b/doc/src/images/qeasingcurve-outquart.png new file mode 100644 index 0000000..d45a0b8 Binary files /dev/null and b/doc/src/images/qeasingcurve-outquart.png differ diff --git a/doc/src/images/qeasingcurve-outquint.png b/doc/src/images/qeasingcurve-outquint.png new file mode 100644 index 0000000..6e7df0e Binary files /dev/null and b/doc/src/images/qeasingcurve-outquint.png differ diff --git a/doc/src/images/qeasingcurve-outsine.png b/doc/src/images/qeasingcurve-outsine.png new file mode 100644 index 0000000..7546a0d Binary files /dev/null and b/doc/src/images/qeasingcurve-outsine.png differ diff --git a/doc/src/images/qeasingcurve-sinecurve.png b/doc/src/images/qeasingcurve-sinecurve.png new file mode 100644 index 0000000..ca67d44 Binary files /dev/null and b/doc/src/images/qeasingcurve-sinecurve.png differ diff --git a/doc/src/images/statemachine-button-history.png b/doc/src/images/statemachine-button-history.png new file mode 100644 index 0000000..7f51cae Binary files /dev/null and b/doc/src/images/statemachine-button-history.png differ diff --git a/doc/src/images/statemachine-button-nested.png b/doc/src/images/statemachine-button-nested.png new file mode 100644 index 0000000..762ac14 Binary files /dev/null and b/doc/src/images/statemachine-button-nested.png differ diff --git a/doc/src/images/statemachine-button.png b/doc/src/images/statemachine-button.png new file mode 100644 index 0000000..10102bd Binary files /dev/null and b/doc/src/images/statemachine-button.png differ diff --git a/doc/src/images/statemachine-customevents.png b/doc/src/images/statemachine-customevents.png new file mode 100644 index 0000000..62a4222 Binary files /dev/null and b/doc/src/images/statemachine-customevents.png differ diff --git a/doc/src/images/statemachine-customevents2.png b/doc/src/images/statemachine-customevents2.png new file mode 100644 index 0000000..57b37ef Binary files /dev/null and b/doc/src/images/statemachine-customevents2.png differ diff --git a/doc/src/images/statemachine-finished.png b/doc/src/images/statemachine-finished.png new file mode 100644 index 0000000..0ac081d Binary files /dev/null and b/doc/src/images/statemachine-finished.png differ diff --git a/doc/src/images/statemachine-nonparallel.png b/doc/src/images/statemachine-nonparallel.png new file mode 100644 index 0000000..f9850a7 Binary files /dev/null and b/doc/src/images/statemachine-nonparallel.png differ diff --git a/doc/src/images/statemachine-parallel.png b/doc/src/images/statemachine-parallel.png new file mode 100644 index 0000000..a65c297 Binary files /dev/null and b/doc/src/images/statemachine-parallel.png differ diff --git a/doc/src/images/stickman-example.png b/doc/src/images/stickman-example.png new file mode 100644 index 0000000..a40f37b Binary files /dev/null and b/doc/src/images/stickman-example.png differ diff --git a/doc/src/images/stickman-example1.png b/doc/src/images/stickman-example1.png new file mode 100644 index 0000000..1596a68 Binary files /dev/null and b/doc/src/images/stickman-example1.png differ diff --git a/doc/src/images/stickman-example2.png b/doc/src/images/stickman-example2.png new file mode 100644 index 0000000..980276a Binary files /dev/null and b/doc/src/images/stickman-example2.png differ diff --git a/doc/src/images/stickman-example3.png b/doc/src/images/stickman-example3.png new file mode 100644 index 0000000..3635ff7 Binary files /dev/null and b/doc/src/images/stickman-example3.png differ diff --git a/doc/src/images/tankgame-example.png b/doc/src/images/tankgame-example.png new file mode 100644 index 0000000..9e17e30 Binary files /dev/null and b/doc/src/images/tankgame-example.png differ diff --git a/doc/src/images/trafficlight-example.png b/doc/src/images/trafficlight-example.png new file mode 100644 index 0000000..3431542 Binary files /dev/null and b/doc/src/images/trafficlight-example.png differ diff --git a/doc/src/images/trafficlight-example1.png b/doc/src/images/trafficlight-example1.png new file mode 100644 index 0000000..ec8c7ff Binary files /dev/null and b/doc/src/images/trafficlight-example1.png differ diff --git a/doc/src/images/trafficlight-example2.png b/doc/src/images/trafficlight-example2.png new file mode 100644 index 0000000..a12e4db Binary files /dev/null and b/doc/src/images/trafficlight-example2.png differ diff --git a/doc/src/snippets/animation/sequential/icons.qrc b/doc/src/snippets/animation/sequential/icons.qrc new file mode 100644 index 0000000..d55f797 --- /dev/null +++ b/doc/src/snippets/animation/sequential/icons.qrc @@ -0,0 +1,6 @@ + + + icons/left.png + icons/right.png + + diff --git a/doc/src/snippets/animation/sequential/icons/left.png b/doc/src/snippets/animation/sequential/icons/left.png new file mode 100644 index 0000000..5dd8da0 Binary files /dev/null and b/doc/src/snippets/animation/sequential/icons/left.png differ diff --git a/doc/src/snippets/animation/sequential/icons/right.png b/doc/src/snippets/animation/sequential/icons/right.png new file mode 100644 index 0000000..ac61326 Binary files /dev/null and b/doc/src/snippets/animation/sequential/icons/right.png differ diff --git a/doc/src/snippets/animation/sequential/main.cpp b/doc/src/snippets/animation/sequential/main.cpp new file mode 100644 index 0000000..aff8f29 --- /dev/null +++ b/doc/src/snippets/animation/sequential/main.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include "tracer.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QWidget window; + window.resize(720, 96); + window.show(); + + QLabel *label1 = new QLabel(&window); + label1->setPixmap(QPixmap(":/icons/left.png")); + label1->move(16, 16); + label1->show(); + + QLabel *label2 = new QLabel(&window); + label2->setPixmap(QPixmap(":/icons/right.png")); + label2->move(320, 16); + label2->show(); + + QPropertyAnimation *anim1 = new QPropertyAnimation(label1, "pos"); + anim1->setDuration(2500); + anim1->setStartValue(QPoint(16, 16)); + anim1->setEndValue(QPoint(320, 16)); + + QPropertyAnimation *anim2 = new QPropertyAnimation(label2, "pos"); + anim2->setDuration(2500); + anim2->setStartValue(QPoint(320, 16)); + anim2->setEndValue(QPoint(640, 16)); + + QSequentialAnimationGroup group; + group.addAnimation(anim1); + group.addAnimation(anim2); + + Tracer tracer(&window); + + QObject::connect(anim1, SIGNAL(valueChanged(QVariant)), + &tracer, SLOT(recordValue(QVariant))); + QObject::connect(anim2, SIGNAL(valueChanged(QVariant)), + &tracer, SLOT(recordValue(QVariant))); + QObject::connect(anim1, SIGNAL(finished()), &tracer, SLOT(checkValue())); + QObject::connect(anim2, SIGNAL(finished()), &tracer, SLOT(checkValue())); + + group.start(); + return app.exec(); +} diff --git a/doc/src/snippets/animation/sequential/sequential.pro b/doc/src/snippets/animation/sequential/sequential.pro new file mode 100644 index 0000000..fcf017f --- /dev/null +++ b/doc/src/snippets/animation/sequential/sequential.pro @@ -0,0 +1,4 @@ +HEADERS = tracer.h +RESOURCES = icons.qrc +SOURCES = main.cpp \ + tracer.cpp diff --git a/doc/src/snippets/animation/sequential/tracer.cpp b/doc/src/snippets/animation/sequential/tracer.cpp new file mode 100644 index 0000000..49bd51e --- /dev/null +++ b/doc/src/snippets/animation/sequential/tracer.cpp @@ -0,0 +1,25 @@ +#include +#include +#include +#include "tracer.h" + +Tracer::Tracer(QObject *parent) + : QObject(parent) +{ +} + +void Tracer::checkValue() +{ + QAbstractAnimation *animation = static_cast(sender()); + if (time != animation->duration()) { + qDebug() << "Animation's last recorded time" << time; + qDebug() << "Expected" << animation->duration(); + } +} + +void Tracer::recordValue(const QVariant &value) +{ + QAbstractAnimation *animation = static_cast(sender()); + this->value = value; + time = animation->currentTime(); +} diff --git a/doc/src/snippets/animation/sequential/tracer.h b/doc/src/snippets/animation/sequential/tracer.h new file mode 100644 index 0000000..1adb018 --- /dev/null +++ b/doc/src/snippets/animation/sequential/tracer.h @@ -0,0 +1,23 @@ +#ifndef TRACER_H +#define TRACER_H + +#include +#include + +class Tracer : public QObject +{ + Q_OBJECT + +public: + Tracer(QObject *parent = 0); + +public slots: + void checkValue(); + void recordValue(const QVariant &value); + +private: + QVariant value; + int time; +}; + +#endif diff --git a/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp b/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp new file mode 100644 index 0000000..65358ea --- /dev/null +++ b/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp @@ -0,0 +1,4 @@ +//! [0] +qreal myEasingFunction(qreal progress); +//! [0] + diff --git a/doc/src/statemachine.qdoc b/doc/src/statemachine.qdoc new file mode 100644 index 0000000..5a89f4d --- /dev/null +++ b/doc/src/statemachine.qdoc @@ -0,0 +1,645 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page statemachine-api.html + \title The State Machine Framework + \brief An overview of the State Machine framework for constructing and executing state graphs. + \ingroup architecture + + \tableofcontents + + The State Machine framework provides classes for creating and executing + state graphs. The concepts and notation are based on those from Harel's + \l{Statecharts: A visual formalism for complex systems}{Statecharts}, which + is also the basis of UML state diagrams. The semantics of state machine + execution are based on \l{State Chart XML: State Machine Notation for + Control Abstraction}{State Chart XML (SCXML)}. + + Statecharts provide a graphical way of modeling how a system reacts to + stimuli. This is done by defining the possible \e states that the system can + be in, and how the system can move from one state to another (\e transitions + between states). A key characteristic of event-driven systems (such as Qt + applications) is that behavior often depends not only on the last or current + event, but also the events that preceded it. With statecharts, this + information is easy to express. + + The State Machine framework provides an API and execution model that can be + used to effectively embed the elements and semantics of statecharts in Qt + applications. The framework integrates tightly with Qt's meta-object system; + for example, transitions between states can be triggered by signals, and + states can be configured to set properties and invoke methods on QObjects. + Qt's event system is used to drive the state machines. + + \section1 A Simple State Machine + + To demonstrate the core functionality of the State Machine API, let's look + at a small example: A state machine with three states, \c s1, \c s2 and \c + s3. The state machine is controlled by a single QPushButton; when the button + is clicked, the machine transitions to another state. Initially, the state + machine is in state \c s1. The statechart for this machine is as follows: + + \img statemachine-button.png + \omit + \caption This is a caption + \endomit + + The following snippet shows the code needed to create such a state machine. + First, we create the state machine and states: + + \code + QStateMachine machine; + QState *s1 = new QState(); + QState *s2 = new QState(); + QState *s3 = new QState(); + \endcode + + Then, we create the transitions by using the QState::addTransition() + function: + + \code + s1->addTransition(button, SIGNAL(clicked()), s2); + s2->addTransition(button, SIGNAL(clicked()), s3); + s3->addTransition(button, SIGNAL(clicked()), s1); + \endcode + + Next, we add the states to the machine and set the machine's initial state: + + \code + machine.addState(s1); + machine.addState(s2); + machine.addState(s3); + machine.setInitialState(s1); + \endcode + + Finally, we start the state machine: + + \code + machine.start(); + \endcode + + The state machine executes asynchronously, i.e. it becomes part of your + application's event loop. + + \section1 Doing Useful Work on State Entry and Exit + + The above state machine merely transitions from one state to another, it + doesn't perform any operations. The QState::assignProperty() function can be + used to have a state set a property of a QObject when the state is + entered. In the following snippet, the value that should be assigned to a + QLabel's text property is specified for each state: + + \code + s1->assignProperty(label, "text", "In state s1"); + s2->assignProperty(label, "text", "In state s2"); + s3->assignProperty(label, "text", "In state s3"); + \endcode + + When any of the states is entered, the label's text will be changed + accordingly. + + The QState::entered() signal is emitted when the state is entered, and the + QState::exited() signal is emitted when the state is exited. In the + following snippet, the button's showMaximized() slot will be called when + state \c s3 is entered, and the button's showMinimized() slot will be called + when \c s3 is exited: + + \code + QObject::connect(s3, SIGNAL(entered()), button, SLOT(showMaximized())); + QObject::connect(s3, SIGNAL(exited()), button, SLOT(showMinimized())); + \endcode + + Custom states can reimplement QAbstractState::onEntry() and + QAbstractState::onExit(). + + \section1 State Machines That Finish + + The state machine defined in the previous section never finishes. In order + for a state machine to be able to finish, it needs to have a top-level \e + final state (QFinalState object). When the state machine enters a top-level + final state, the machine will emit the QStateMachine::finished() signal and + halt. + + All you need to do to introduce a final state in the graph is create a + QFinalState object and use it as the target of one or more transitions. + + \section1 Sharing Transitions By Grouping States + + Assume we wanted the user to be able to quit the application at any time by + clicking a Quit button. In order to achieve this, we need to create a final + state and make it the target of a transition associated with the Quit + button's clicked() signal. We could add a transition from each of \c s1, \c + s2 and \c s3; however, this seems redundant, and one would also have to + remember to add such a transition from every new state that is added in the + future. + + We can achieve the same behavior (namely that clicking the Quit button quits + the state machine, regardless of which state the state machine is in) by + grouping states \c s1, \c s2 and \c s3. This is done by creating a new + top-level state and making the three original states children of the new + state. The following diagram shows the new state machine. + + \img statemachine-button-nested.png + \omit + \caption This is a caption + \endomit + + The three original states have been renamed \c s11, \c s12 and \c s13 to + reflect that they are now children of the new top-level state, \c s1. Child + states implicitly inherit the transitions of their parent state. This means + it is now sufficient to add a single transition from \c s1 to the final + state \c s2. New states added to \c s1 will also automatically inherit this + transition. + + All that's needed to group states is to specify the proper parent when the + state is created. You also need to specify which of the child states is the + initial one (i.e. which child state the state machine should enter when the + parent state is the target of a transition). + + \code + QState *s1 = new QState(); + QState *s11 = new QState(s1); + QState *s12 = new QState(s1); + QState *s13 = new QState(s1); + s1->setInitialState(s11); + machine.addState(s1); + \endcode + + \code + QFinalState *s2 = new QFinalState(); + s1->addTransition(quitButton, SIGNAL(clicked()), s2); + machine.addState(s2); + + QObject::connect(&machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit())); + \endcode + + In this case we want the application to quit when the state machine is + finished, so the machine's finished() signal is connected to the + application's quit() slot. + + A child state can override an inherited transition. For example, the + following code adds a transition that effectively causes the Quit button to + be ignored when the state machine is in state \c s12. + + \code + s12>addTransition(quitButton, SIGNAL(clicked()), s12); + \endcode + + A transition can have any state as its target, i.e. the target state does + not have to be on the same level in the state hierarchy as the source state. + + \section1 Using History States to Save and Restore the Current State + + Imagine that we wanted to add an "interrupt" mechanism to the example + discussed in the previous section; the user should be able to click a button + to have the state machine perform some non-related task, after which the + state machine should resume whatever it was doing before (i.e. return to the + old state, which is one of \c s11, \c s12 and \c s13 in this case). + + Such behavior can easily be modeled using \e{history states}. A history + state (QHistoryState object) is a pseudo-state that represents the child + state that the parent state was in the last time the parent state was + exited. + + A history state is created as a child of the state for which we wish to + record the current child state; when the state machine detects the presence + of such a state at runtime, it automatically records the current (real) + child state when the parent state is exited. A transition to the history + state is in fact a transition to the child state that the state machine had + previously saved; the state machine automatically "forwards" the transition + to the real child state. + + The following diagram shows the state machine after the interrupt mechanism + has been added. + + \img statemachine-button-history.png + \omit + \caption This is a caption + \endomit + + The following code shows how it can be implemented; in this example we + simply display a message box when \c s3 is entered, then immediately return + to the previous child state of \c s1 via the history state. + + \code + QHistoryState *s1h = s1->addHistoryState(); + + QState *s3 = new QState(); + s3->assignProperty(label, "text", "In s3"); + QMessageBox mbox; + mbox.addButton(QMessageBox::Ok); + mbox.setText("Interrupted!"); + mbox.setIcon(QMessageBox::Information); + QObject::connect(s3, SIGNAL(entered()), &mbox, SLOT(exec())); + s3->addTransition(s1h); + machine.addState(s3); + + s1->addTransition(interruptButton, SIGNAL(clicked()), s3); + \endcode + + \section1 Using Parallel States to Avoid a Combinatorial Explosion of States + + Assume that you wanted to model a set of mutually exclusive properties of a + car in a single state machine. Let's say the properties we are interested in + are Clean vs Dirty, and Moving vs Not moving. It would take four mutually + exclusive states and eight transitions to be able to represent and freely + move between all possible combinations. + + \img statemachine-nonparallel.png + \omit + \caption This is a caption + \endomit + + If we added a third property (say, Red vs Blue), the total number of states + would double, to eight; and if we added a fourth property (say, Enclosed vs + Convertible), the total number of states would double again, to 16. + + Using parallel states, the total number of states and transitions grows + linearly as we add more properties, instead of exponentially. Furthermore, + states can be added to or removed from the parallel state without affecting + any of their sibling states. + + \img statemachine-parallel.png + \omit + \caption This is a caption + \endomit + + To create a parallel state group, pass QState::ParallelStates to the QState + constructor. + + \code + QState *s1 = new QState(QState::ParallelStates); + // s11 and s12 will be entered in parallel + QState *s11 = new QState(s1); + QState *s12 = new QState(s1); + \endcode + + When a parallel state group is entered, all its child states will be + simultaneously entered. Transitions within the individual child states + operate normally. However, any of the child states may take a transition + outside the parent state. When this happens, the parent state and all of its + child states are exited. + + \section1 Detecting that a Composite State has Finished + + A child state can be final (a QFinalState object); when a final child state + is entered, the parent state emits the QState::finished() signal. The + following diagram shows a composite state \c s1 which does some processing + before entering a final state: + + \img statemachine-finished.png + \omit + \caption This is a caption + \endomit + + When \c s1 's final state is entered, \c s1 will automatically emit + finished(). We use a signal transition to cause this event to trigger a + state change: + + \code + s1->addTransition(s1, SIGNAL(finished()), s2); + \endcode + + Using final states in composite states is useful when you want to hide the + internal details of a composite state; i.e. the only thing the outside world + should be able to do is enter the state, and get a notification when the + state has completed its work. This is a very powerful abstraction and + encapsulation mechanism when building complex (deeply nested) state + machines. (In the above example, you could of course create a transition + directly from \c s1 's \c done state rather than relying on \c s1 's + finished() signal, but with the consequence that implementation details of + \c s1 are exposed and depended on). + + For parallel state groups, the QState::finished() signal is emitted when \e + all the child states have entered final states. + + \section1 Events, Transitions and Guards + + A QStateMachine runs its own event loop. For signal transitions + (QSignalTransition objects), QStateMachine automatically posts a + QSignalEvent to itself when it intercepts the corresponding signal; + similarly, for QObject event transitions (QEventTransition objects) a + QWrappedEvent is posted. + + You can post your own events to the state machine using + QStateMachine::postEvent(). + + When posting a custom event to the state machine, you typically also have + one or more custom transitions that can be triggered from events of that + type. To create such a transition, you subclass QAbstractTransition and + reimplement QAbstractTransition::eventTest(), where you check if an event + matches your event type (and optionally other criteria, e.g. attributes of + the event object). + + Here we define our own custom event type, \c StringEvent, for posting + strings to the state machine: + + \code + struct StringEvent : public QEvent + { + StringEvent(const QString &val) + : QEvent(QEvent::Type(QEvent::User+1)), + value(val) {} + + QString value; + }; + \endcode + + Next, we define a transition that only triggers when the event's string + matches a particular string (a \e guarded transition): + + \code + class StringTransition : public QAbstractTransition + { + public: + StringTransition(const QString &value) + : m_value(value) {} + + protected: + virtual bool eventTest(QEvent *e) const + { + if (e->type() != QEvent::Type(QEvent::User+1)) // StringEvent + return false; + StringEvent *se = static_cast(e); + return (m_value == se->value); + } + + virtual void onTransition(QEvent *) {} + + private: + QString m_value; + }; + \endcode + + In the eventTest() reimplementation, we first check if the event type is the + desired one; if so, we cast the event to a StringEvent and perform the + string comparison. + + The following is a statechart that uses the custom event and transition: + + \img statemachine-customevents.png + \omit + \caption This is a caption + \endomit + + Here's what the implementation of the statechart looks like: + + \code + QStateMachine machine; + QState *s1 = new QState(); + QState *s2 = new QState(); + QFinalState *done = new QFinalState(); + + StringTransition *t1 = new StringTransition("Hello"); + t1->setTargetState(s2); + s1->addTransition(t1); + StringTransition *t2 = new StringTransition("world"); + t2->setTargetState(done); + s2->addTransition(t2); + + machine.addState(s1); + machine.addState(s2); + machine.addState(done); + machine.setInitialState(s1); + \endcode + + Once the machine is started, we can post events to it. + + \code + machine.postEvent(new StringEvent("Hello")); + machine.postEvent(new StringEvent("world")); + \endcode + + An event that is not handled by any relevant transition will be silently + consumed by the state machine. It can be useful to group states and provide + a default handling of such events; for example, as illustrated in the + following statechart: + + \img statemachine-customevents2.png + \omit + \caption This is a caption + \endomit + + For deeply nested statecharts, you can add such "fallback" transitions at + the level of granularity that's most appropriate. + + \section1 Using Restore Policy To Automatically Restore Properties + + In some state machines it can be useful to focus the attention on assigning properties in states, + not on restoring them when the state is no longer active. If you know that a property should + always be restored to its initial value when the machine enters a state that does not explicitly + give the property a value, you can set the global restore policy to + QStateMachine::RestoreProperties. + + \code + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + \endcode + + When this restore policy is set, the machine will automatically restore all properties. If it + enters a state where a given property is not set, it will first search the hierarchy of ancestors + to see if the property is defined there. If it is, the property will be restored to the value + defined by the closest ancestor. If not, it will be restored to its initial value (i.e. the + value of the property before any property assignments in states were executed.) + + Take the following code: + \code + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QState *s1 = new QState(); + s1->assignProperty(object, "fooBar", 1.0); + machine.addState(s1); + machine.setInitialState(s1); + + QState *s2 = new QState(); + machine.addState(s2); + \endcode + + Lets say the property \c fooBar is 0.0 when the machine starts. When the machine is in state + \c s1, the property will be 1.0, since the state explicitly assigns this value to it. When the + machine is in state \c s2, no value is explicitly defined for the property, so it will implicitly + be restored to 0.0. + + If we are using nested states, the parent defines a value for the property which is inherited by + all descendants that do not explicitly assign a value to the property. + \code + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QState *s1 = new QState(); + s1->assignProperty(object, "fooBar", 1.0); + machine.addState(s1); + machine.setInitialState(s1); + + QState *s2 = new QState(s1); + s2->assignProperty(object, "fooBar", 2.0); + s1->setInitialState(s2); + + QState *s3 = new QState(s1); + \endcode + + Here \c s1 has two children: \c s2 and \c s3. When \c s2 is entered, the property \c fooBar + will have the value 2.0, since this is explicitly defined for the state. When the machine is in + state \c s3, no value is defined for the state, but \c s1 defines the property to be 1.0, so this + is the value that will be assigned to \c fooBar. + + \section1 Animating Property Assignments + + The State Machine API connects with the Animation API in Qt to allow automatically animating + properties as they are assigned in states. + + Say we have the following code: + \code + QState *s1 = new QState(); + QState *s2 = new QState(); + + s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); + s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100)); + + s1->addTransition(button, SIGNAL(clicked()), s2); + \endcode + + Here we define two states of a user interface. In \c s1 the \c button is small, and in \c s2 + it is bigger. If we click the button to transition from \c s1 to \c s2, the geometry of the button + will be set immediately when a given state has been entered. If we want the transition to be + smooth, however, all we need to do is make a QPropertyAnimation and add this to the transition + object. + + \code + QState *s1 = new QState(); + QState *s2 = new QState(); + + s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); + s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100)); + + QSignalTransition *transition = s1->addTransition(button, SIGNAL(clicked()), s2); + transition->addAnimation(new QPropertyAnimation(button, "geometry")); + \endcode + + Adding an animation for the property in question means that the property assignment will no + longer take immediate effect when the state has been entered. Instead, the animation will start + playing when the state has been entered and smoothly animate the property assignment. Since we + do not set the start value or end value of the animation, these will be set implicitly. The + start value of the animation will be the property's current value when the animation starts, and + the end value will be set based on the property assignments defined for the state. + + If the global restore policy of the state machine is set to QStateMachine::RestoreProperties, + it is possible to also add animations for the property restorations. + + \section1 Detecting That All Properties Have Been Set In A State + + When animations are used to assign properties, a state no longer defines the exact values that a + property will have when the machine is in the given state. While the animation is running, the + property can potentially have any value, depending on the animation. + + In some cases, it can be useful to be able to detect when the property has actually been assigned + the value defined by a state. For this, we can use the state's polished() signal. + \code + QState *s1 = new QState(); + s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); + + QState *s2 = new QState(); + + s1->addTransition(s1, SIGNAL(polished()), s2); + \endcode + + The machine will be in state \c s1 until the \c geometry property has been set. Then it will + immediately transition into \c s2. If the transition into \c s1 has an animation for the \c + geometry property, then the machine will stay in \c s1 until the animation has finished. If there + is no animation, it will simply set the property and immediately enter state \c s2. + + Either way, when the machine is in state \c s2, the property \c geometry has been assigned the + defined value. + + If the global restore policy is set to QStateMachine::RestoreProperties, the state will not emit + the polished() signal until these have been executed as well. + + \section1 What happens if a state is exited before the animation has finished + + If a state has property assignments, and the transition into the state has animations for the + properties, the state can potentially be exited before the properties have been assigned to the + values defines by the state. This is true in particular when there are transitions out from the + state that do not depend on the state being polished, as described in the previous section. + + The State Machine API guarantees that a property assigned by the state machine either: + \list + \o Has a value explicitly assigned to the property. + \o Is currently being animated into a value explicitly assigned to the property. + \endlist + + When a state is exited prior to the animation finishing, the behavior of the state machine depends + on the target state of the transition. If the target state explicitly assigns a value to the + property, no additional action will be taken. The property will be assigned the value defined by + the target state. + + If the target state does not assign any value to the property, there are two + options: By default, the property will be assigned the value defined by the state it is leaving + (the value it would have been assigned if the animation had been permitted to finish playing.) If + a global restore policy is set, however, this will take precedence, and the property will be + restored as usual. + + \section1 Default Animations + + As described earlier, you can add animations to transitions to make sure property assignments + in the target state are animated. If you want a specific animation to be used for a given property + regardless of which transition is taken, you can add it as a default animation to the state + machine. This is in particular useful when the properties assigned (or restored) by specific + states is not known when the machine is constructed. + + \code + QState *s1 = new QState(); + QState *s2 = new QState(); + + s2->assignProperty(object, "fooBar", 2.0); + s1->addTransition(s2); + + QStateMachine machine; + machine.setInitialState(s1); + machine.addDefaultAnimation(new QPropertyAnimation(object, "fooBar")); + \endcode + + When the machine is in state \c s2, the machine will play the default animation for the + property \c fooBar since this property is assigned by \c s2. + + Note that animations explicitly set on transitions will take precedence over any default + animation for the given property. +*/ diff --git a/examples/animation/README b/examples/animation/README new file mode 100644 index 0000000..6a892f8 --- /dev/null +++ b/examples/animation/README @@ -0,0 +1,38 @@ +The animation framework aims to provide an easy way for creating animated and +smooth GUI's. By animating Qt properties, the framework provides great freedom +for animating widgets and other QObjects. The framework can also be used with +the Graphics View framework. + +The example launcher provided with Qt can be used to explore each of the +examples in this directory. + +Documentation for these examples can be found via the Tutorial and Examples +link in the main Qt documentation. + + +Finding the Qt Examples and Demos launcher +========================================== + +On Windows: + +The launcher can be accessed via the Windows Start menu. Select the menu +entry entitled "Qt Examples and Demos" entry in the submenu containing +the Qt tools. + +On Mac OS X: + +For the binary distribution, the qtdemo executable is installed in the +/Developer/Applications/Qt directory. For the source distribution, it is +installed alongside the other Qt tools on the path specified when Qt is +configured. + +On Unix/Linux: + +The qtdemo executable is installed alongside the other Qt tools on the path +specified when Qt is configured. + +On all platforms: + +The source code for the launcher can be found in the demos/qtdemo directory +in the Qt package. This example is built at the same time as the Qt libraries, +tools, examples, and demonstrations. diff --git a/examples/animation/animatedtiles/animatedtiles.pro b/examples/animation/animatedtiles/animatedtiles.pro new file mode 100644 index 0000000..1840b17 --- /dev/null +++ b/examples/animation/animatedtiles/animatedtiles.pro @@ -0,0 +1,8 @@ +SOURCES = main.cpp +RESOURCES = animatedtiles.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/animatedtiles +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS animatedtiles.pro images +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/animatedtiles +INSTALLS += target sources diff --git a/examples/animation/animatedtiles/animatedtiles.qrc b/examples/animation/animatedtiles/animatedtiles.qrc new file mode 100644 index 0000000..c43a979 --- /dev/null +++ b/examples/animation/animatedtiles/animatedtiles.qrc @@ -0,0 +1,11 @@ + + + images/Time-For-Lunch-2.jpg + images/centered.png + images/ellipse.png + images/figure8.png + images/kinetic.png + images/random.png + images/tile.png + + diff --git a/examples/animation/animatedtiles/images/Time-For-Lunch-2.jpg b/examples/animation/animatedtiles/images/Time-For-Lunch-2.jpg new file mode 100644 index 0000000..c57a555 Binary files /dev/null and b/examples/animation/animatedtiles/images/Time-For-Lunch-2.jpg differ diff --git a/examples/animation/animatedtiles/images/centered.png b/examples/animation/animatedtiles/images/centered.png new file mode 100644 index 0000000..e416156 Binary files /dev/null and b/examples/animation/animatedtiles/images/centered.png differ diff --git a/examples/animation/animatedtiles/images/ellipse.png b/examples/animation/animatedtiles/images/ellipse.png new file mode 100644 index 0000000..2c3ba88 Binary files /dev/null and b/examples/animation/animatedtiles/images/ellipse.png differ diff --git a/examples/animation/animatedtiles/images/figure8.png b/examples/animation/animatedtiles/images/figure8.png new file mode 100644 index 0000000..6b05804 Binary files /dev/null and b/examples/animation/animatedtiles/images/figure8.png differ diff --git a/examples/animation/animatedtiles/images/kinetic.png b/examples/animation/animatedtiles/images/kinetic.png new file mode 100644 index 0000000..55cfa55 Binary files /dev/null and b/examples/animation/animatedtiles/images/kinetic.png differ diff --git a/examples/animation/animatedtiles/images/random.png b/examples/animation/animatedtiles/images/random.png new file mode 100644 index 0000000..415d96f Binary files /dev/null and b/examples/animation/animatedtiles/images/random.png differ diff --git a/examples/animation/animatedtiles/images/tile.png b/examples/animation/animatedtiles/images/tile.png new file mode 100644 index 0000000..c8f39d8 Binary files /dev/null and b/examples/animation/animatedtiles/images/tile.png differ diff --git a/examples/animation/animatedtiles/main.cpp b/examples/animation/animatedtiles/main.cpp new file mode 100644 index 0000000..4b1d99d --- /dev/null +++ b/examples/animation/animatedtiles/main.cpp @@ -0,0 +1,280 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class Pixmap : public QObject, public QGraphicsPixmapItem +{ + Q_OBJECT + Q_PROPERTY(QPointF pos READ pos WRITE setPos) +public: + Pixmap(const QPixmap &pix) + : QObject(), QGraphicsPixmapItem(pix) + { + setCacheMode(DeviceCoordinateCache); + } +}; + +class Button : public QGraphicsWidget +{ + Q_OBJECT +public: + Button(const QPixmap &pixmap, QGraphicsItem *parent = 0) + : QGraphicsWidget(parent), _pix(pixmap) + { + setAcceptHoverEvents(true); + setCacheMode(DeviceCoordinateCache); + } + + QRectF boundingRect() const + { + return QRectF(-65, -65, 130, 130); + } + + QPainterPath shape() const + { + QPainterPath path; + path.addEllipse(boundingRect()); + return path; + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) + { + bool down = option->state & QStyle::State_Sunken; + QRectF r = boundingRect(); + QLinearGradient grad(r.topLeft(), r.bottomRight()); + grad.setColorAt(down ? 1 : 0, option->state & QStyle::State_MouseOver ? Qt::white : Qt::lightGray); + grad.setColorAt(down ? 0 : 1, Qt::darkGray); + painter->setPen(Qt::darkGray); + painter->setBrush(grad); + painter->drawEllipse(r); + QLinearGradient grad2(r.topLeft(), r.bottomRight()); + grad.setColorAt(down ? 1 : 0, Qt::darkGray); + grad.setColorAt(down ? 0 : 1, Qt::lightGray); + painter->setPen(Qt::NoPen); + painter->setBrush(grad); + if (down) + painter->translate(2, 2); + painter->drawEllipse(r.adjusted(5, 5, -5, -5)); + painter->drawPixmap(-_pix.width()/2, -_pix.height()/2, _pix); + } + +signals: + void pressed(); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *) + { + emit pressed(); + update(); + } + + void mouseReleaseEvent(QGraphicsSceneMouseEvent *) + { + update(); + } + +private: + QPixmap _pix; +}; + +class View : public QGraphicsView +{ +public: + View(QGraphicsScene *scene) : QGraphicsView(scene) { } + +protected: + void resizeEvent(QResizeEvent *event) + { + QGraphicsView::resizeEvent(event); + fitInView(sceneRect(), Qt::KeepAspectRatio); + } +}; + +int main(int argc, char **argv) +{ + Q_INIT_RESOURCE(animatedtiles); + + QApplication app(argc, argv); + + QPixmap kineticPix(":/images/kinetic.png"); + QPixmap bgPix(":/images/Time-For-Lunch-2.jpg"); + + QGraphicsScene scene(-350, -350, 700, 700); + + QList items; + for (int i = 0; i < 64; ++i) { + Pixmap *item = new Pixmap(kineticPix); + item->setOffset(-kineticPix.width()/2, -kineticPix.height()/2); + item->setZValue(i); + items << item; + scene.addItem(item); + } + + // Buttons + QGraphicsItem *buttonParent = new QGraphicsRectItem; + Button *ellipseButton = new Button(QPixmap(":/images/ellipse.png"), buttonParent); + Button *figure8Button = new Button(QPixmap(":/images/figure8.png"), buttonParent); + Button *randomButton = new Button(QPixmap(":/images/random.png"), buttonParent); + Button *tiledButton = new Button(QPixmap(":/images/tile.png"), buttonParent); + Button *centeredButton = new Button(QPixmap(":/images/centered.png"), buttonParent); + + ellipseButton->setPos(-100, -100); + figure8Button->setPos(100, -100); + randomButton->setPos(0, 0); + tiledButton->setPos(-100, 100); + centeredButton->setPos(100, 100); + + scene.addItem(buttonParent); + buttonParent->scale(0.75, 0.75); + buttonParent->setPos(200, 200); + buttonParent->setZValue(65); + + // States + QState *rootState = new QState; + QState *ellipseState = new QState(rootState); + QState *figure8State = new QState(rootState); + QState *randomState = new QState(rootState); + QState *tiledState = new QState(rootState); + QState *centeredState = new QState(rootState); + + // Values + for (int i = 0; i < 64; ++i) { + Pixmap *item = items.at(i); + // Ellipse + ellipseState->assignProperty(item, "pos", + QPointF(cos((i / 63.0) * 6.28) * 250, + sin((i / 63.0) * 6.28) * 250)); + + // Figure 8 + figure8State->assignProperty(item, "pos", + QPointF(sin((i / 63.0) * 6.28) * 250, + sin(((i * 2)/63.0) * 6.28) * 250)); + + // Random + randomState->assignProperty(item, "pos", + QPointF(-250 + qrand() % 500, + -250 + qrand() % 500)); + + // Tiled + tiledState->assignProperty(item, "pos", + QPointF(((i % 8) - 4) * kineticPix.width() + kineticPix.width() / 2, + ((i / 8) - 4) * kineticPix.height() + kineticPix.height() / 2)); + + // Centered + centeredState->assignProperty(item, "pos", QPointF()); + } + + // Ui + View *view = new View(&scene); + view->setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Animated Tiles")); + view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); + view->setBackgroundBrush(bgPix); + view->setCacheMode(QGraphicsView::CacheBackground); + view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + view->show(); + + QStateMachine states; + states.addState(rootState); + states.setInitialState(rootState); + rootState->setInitialState(centeredState); + + QParallelAnimationGroup *group = new QParallelAnimationGroup; + for (int i = 0; i < 64; ++i) { + QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); + anim->setDuration(750 + i * 25); + anim->setEasingCurve(QEasingCurve::InOutBack); + group->addAnimation(anim); + } + QAbstractTransition *trans = rootState->addTransition(ellipseButton, SIGNAL(pressed()), ellipseState); + trans->addAnimation(group); + + group = new QParallelAnimationGroup; + for (int i = 0; i < 64; ++i) { + QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); + anim->setDuration(750 + i * 25); + anim->setEasingCurve(QEasingCurve::InOutBack); + group->addAnimation(anim); + } + trans = rootState->addTransition(figure8Button, SIGNAL(pressed()), figure8State); + trans->addAnimation(group); + + group = new QParallelAnimationGroup; + for (int i = 0; i < 64; ++i) { + QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); + anim->setDuration(750 + i * 25); + anim->setEasingCurve(QEasingCurve::InOutBack); + group->addAnimation(anim); + } + trans = rootState->addTransition(randomButton, SIGNAL(pressed()), randomState); + trans->addAnimation(group); + + group = new QParallelAnimationGroup; + for (int i = 0; i < 64; ++i) { + QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); + anim->setDuration(750 + i * 25); + anim->setEasingCurve(QEasingCurve::InOutBack); + group->addAnimation(anim); + } + trans = rootState->addTransition(tiledButton, SIGNAL(pressed()), tiledState); + trans->addAnimation(group); + + group = new QParallelAnimationGroup; + for (int i = 0; i < 64; ++i) { + QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); + anim->setDuration(750 + i * 25); + anim->setEasingCurve(QEasingCurve::InOutBack); + group->addAnimation(anim); + } + trans = rootState->addTransition(centeredButton, SIGNAL(pressed()), centeredState); + trans->addAnimation(group); + + states.start(); + QTimer timer; + timer.start(125); + timer.setSingleShot(true); + rootState->addTransition(&timer, SIGNAL(timeout()), ellipseState); + + return app.exec(); +} + +#include "main.moc" diff --git a/examples/animation/animation.pro b/examples/animation/animation.pro new file mode 100644 index 0000000..9a2874b --- /dev/null +++ b/examples/animation/animation.pro @@ -0,0 +1,16 @@ +TEMPLATE = \ + subdirs +SUBDIRS += \ + animatedtiles \ + appchooser \ + easing \ + moveblocks \ + states \ + stickman \ + sub-attaq + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS animation.pro README +sources.path = $$[QT_INSTALL_EXAMPLES]/animation +INSTALLS += target sources diff --git a/examples/animation/appchooser/accessories-dictionary.png b/examples/animation/appchooser/accessories-dictionary.png new file mode 100644 index 0000000..e9bd55d Binary files /dev/null and b/examples/animation/appchooser/accessories-dictionary.png differ diff --git a/examples/animation/appchooser/akregator.png b/examples/animation/appchooser/akregator.png new file mode 100644 index 0000000..a086f45 Binary files /dev/null and b/examples/animation/appchooser/akregator.png differ diff --git a/examples/animation/appchooser/appchooser.pro b/examples/animation/appchooser/appchooser.pro new file mode 100644 index 0000000..847b60a --- /dev/null +++ b/examples/animation/appchooser/appchooser.pro @@ -0,0 +1,8 @@ +SOURCES = main.cpp +RESOURCES = appchooser.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/appchooser +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS appchooser.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/appchooser +INSTALLS += target sources diff --git a/examples/animation/appchooser/appchooser.qrc b/examples/animation/appchooser/appchooser.qrc new file mode 100644 index 0000000..28a3e1c --- /dev/null +++ b/examples/animation/appchooser/appchooser.qrc @@ -0,0 +1,8 @@ + + + accessories-dictionary.png + akregator.png + digikam.png + k3b.png + + diff --git a/examples/animation/appchooser/digikam.png b/examples/animation/appchooser/digikam.png new file mode 100644 index 0000000..9de9fb2 Binary files /dev/null and b/examples/animation/appchooser/digikam.png differ diff --git a/examples/animation/appchooser/k3b.png b/examples/animation/appchooser/k3b.png new file mode 100644 index 0000000..bbcafcf Binary files /dev/null and b/examples/animation/appchooser/k3b.png differ diff --git a/examples/animation/appchooser/main.cpp b/examples/animation/appchooser/main.cpp new file mode 100644 index 0000000..44457f7 --- /dev/null +++ b/examples/animation/appchooser/main.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + + +class Pixmap : public QGraphicsWidget +{ + Q_OBJECT + +public: + Pixmap(const QPixmap &pix, QGraphicsItem *parent = 0) + : QGraphicsWidget(parent), orig(pix), p(pix) + { + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + { + painter->drawPixmap(QPointF(), p); + } + + virtual void mousePressEvent(QGraphicsSceneMouseEvent * ) + { + emit clicked(); + } + + virtual void setGeometry(const QRectF &rect) + { + QGraphicsWidget::setGeometry(rect); + + if (rect.size().width() > orig.size().width()) + p = orig.scaled(rect.size().toSize()); + else + p = orig; + } + +Q_SIGNALS: + void clicked(); + +private: + QPixmap orig; + QPixmap p; +}; + +void createStates(const QObjectList &objects, + const QRect &selectedRect, QState *parent) +{ + for (int i = 0; i < objects.size(); ++i) { + QState *state = new QState(parent); + state->assignProperty(objects.at(i), "geometry", selectedRect); + parent->addTransition(objects.at(i), SIGNAL(clicked()), state); + } +} + +void createAnimations(const QObjectList &objects, QStateMachine *machine) +{ + for (int i=0; iaddDefaultAnimation(new QPropertyAnimation(objects.at(i), "geometry")); +} + +int main(int argc, char **argv) +{ + Q_INIT_RESOURCE(appchooser); + + QApplication app(argc, argv); + + Pixmap *p1 = new Pixmap(QPixmap(":/digikam.png")); + Pixmap *p2 = new Pixmap(QPixmap(":/akregator.png")); + Pixmap *p3 = new Pixmap(QPixmap(":/accessories-dictionary.png")); + Pixmap *p4 = new Pixmap(QPixmap(":/k3b.png")); + + p1->setObjectName("p1"); + p2->setObjectName("p2"); + p3->setObjectName("p3"); + p4->setObjectName("p4"); + + p1->setGeometry(QRectF(0.0, 0.0, 64.0, 64.0)); + p2->setGeometry(QRectF(236.0, 0.0, 64.0, 64.0)); + p3->setGeometry(QRectF(236.0, 236.0, 64.0, 64.0)); + p4->setGeometry(QRectF(0.0, 236.0, 64.0, 64.0)); + + QGraphicsScene scene(0, 0, 300, 300); + scene.setBackgroundBrush(Qt::white); + scene.addItem(p1); + scene.addItem(p2); + scene.addItem(p3); + scene.addItem(p4); + + QGraphicsView window(&scene); + window.setFrameStyle(0); + window.setAlignment(Qt::AlignLeft | Qt::AlignTop); + window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QState *group = new QState(machine.rootState()); + group->setObjectName("group"); + QRect selectedRect(86, 86, 128, 128); + + QState *idleState = new QState(group); + group->setInitialState(idleState); + + QObjectList objects; + objects << p1 << p2 << p3 << p4; + createStates(objects, selectedRect, group); + createAnimations(objects, &machine); + + machine.setInitialState(group); + machine.start(); + + window.resize(300, 300); + window.show(); + + return app.exec(); +} + +#include "main.moc" diff --git a/examples/animation/easing/animation.h b/examples/animation/easing/animation.h new file mode 100644 index 0000000..d4d699d --- /dev/null +++ b/examples/animation/easing/animation.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANIMATION_H +#define ANIMATION_H + +#include + +#include + +class Animation : public QPropertyAnimation { +public: + enum PathType { + LinearPath, + CirclePath, + NPathTypes + }; + Animation(QObject *target, const QByteArray &prop) + : QPropertyAnimation(target, prop) + { + setPathType(LinearPath); + } + + void setPathType(PathType pathType) + { + if (pathType >= NPathTypes) + qWarning("Unknown pathType %d", pathType); + + m_pathType = pathType; + m_path = QPainterPath(); + } + + void updateCurrentTime(int msecs) + { + if (m_pathType == CirclePath) { + if (m_path.isEmpty()) { + QPointF to = endValue().toPointF(); + QPointF from = startValue().toPointF(); + m_path.moveTo(from); + m_path.addEllipse(QRectF(from, to)); + } + int dura = duration(); + const qreal progress = ((dura == 0) ? 1 : ((((currentTime() - 1) % dura) + 1) / qreal(dura))); + + qreal easedProgress = easingCurve().valueForProgress(progress); + if (easedProgress > 1.0) { + easedProgress -= 1.0; + } else if (easedProgress < 0) { + easedProgress += 1.0; + } + QPointF pt = m_path.pointAtPercent(easedProgress); + updateCurrentValue(pt); + emit valueChanged(pt); + } else { + QPropertyAnimation::updateCurrentTime(msecs); + } + } + + QPainterPath m_path; + PathType m_pathType; +}; + +#endif // ANIMATION_H diff --git a/examples/animation/easing/easing.pro b/examples/animation/easing/easing.pro new file mode 100644 index 0000000..8e8a35f --- /dev/null +++ b/examples/animation/easing/easing.pro @@ -0,0 +1,14 @@ +HEADERS = window.h \ + animation.h +SOURCES = main.cpp \ + window.cpp + +FORMS = form.ui + +RESOURCES = easing.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/easing +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS easing.pro images +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/easing +INSTALLS += target sources diff --git a/examples/animation/easing/easing.qrc b/examples/animation/easing/easing.qrc new file mode 100644 index 0000000..7e112d3 --- /dev/null +++ b/examples/animation/easing/easing.qrc @@ -0,0 +1,5 @@ + + + images/qt-logo.png + + \ No newline at end of file diff --git a/examples/animation/easing/form.ui b/examples/animation/easing/form.ui new file mode 100644 index 0000000..b60ade8 --- /dev/null +++ b/examples/animation/easing/form.ui @@ -0,0 +1,201 @@ + + + Form + + + + 0 + 0 + 545 + 471 + + + + Easing curves + + + + + + + 0 + 0 + + + + + 16777215 + 120 + + + + Qt::ScrollBarAlwaysOff + + + QListView::Static + + + false + + + QListView::IconMode + + + false + + + + + + + + + Path type + + + + + + Line + + + true + + + buttonGroup + + + + + + + Circle + + + buttonGroup + + + + + + + + + + + 0 + 0 + + + + Properties + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Period + + + + + + + false + + + -1.000000000000000 + + + 0.100000000000000 + + + -1.000000000000000 + + + + + + + Amplitude + + + + + + + false + + + -1.000000000000000 + + + 0.100000000000000 + + + -1.000000000000000 + + + + + + + Overshoot + + + + + + + false + + + -1.000000000000000 + + + 0.100000000000000 + + + -1.000000000000000 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + diff --git a/examples/animation/easing/images/qt-logo.png b/examples/animation/easing/images/qt-logo.png new file mode 100644 index 0000000..14ddf2a Binary files /dev/null and b/examples/animation/easing/images/qt-logo.png differ diff --git a/examples/animation/easing/main.cpp b/examples/animation/easing/main.cpp new file mode 100644 index 0000000..bd10df2 --- /dev/null +++ b/examples/animation/easing/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "window.h" + +int main(int argc, char **argv) +{ + Q_INIT_RESOURCE(easing); + QApplication app(argc, argv); + Window w; + w.resize(400, 400); + w.show(); + return app.exec(); +} diff --git a/examples/animation/easing/window.cpp b/examples/animation/easing/window.cpp new file mode 100644 index 0000000..cf4be15 --- /dev/null +++ b/examples/animation/easing/window.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "window.h" + +Window::Window(QWidget *parent) + : QWidget(parent), m_iconSize(64, 64) +{ + m_ui.setupUi(this); + QButtonGroup *buttonGroup = qFindChild(this); // ### workaround for uic in 4.4 + m_ui.easingCurvePicker->setIconSize(m_iconSize); + m_ui.easingCurvePicker->setMinimumHeight(m_iconSize.height() + 50); + buttonGroup->setId(m_ui.lineRadio, 0); + buttonGroup->setId(m_ui.circleRadio, 1); + + QEasingCurve dummy; + m_ui.periodSpinBox->setValue(dummy.period()); + m_ui.amplitudeSpinBox->setValue(dummy.amplitude()); + m_ui.overshootSpinBox->setValue(dummy.overshoot()); + + connect(m_ui.easingCurvePicker, SIGNAL(currentRowChanged(int)), this, SLOT(curveChanged(int))); + connect(buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(pathChanged(int))); + connect(m_ui.periodSpinBox, SIGNAL(valueChanged(double)), this, SLOT(periodChanged(double))); + connect(m_ui.amplitudeSpinBox, SIGNAL(valueChanged(double)), this, SLOT(amplitudeChanged(double))); + connect(m_ui.overshootSpinBox, SIGNAL(valueChanged(double)), this, SLOT(overshootChanged(double))); + createCurveIcons(); + + QPixmap pix(QLatin1String(":/images/qt-logo.png")); + m_item = new PixmapItem(pix); + m_scene.addItem(m_item); + m_ui.graphicsView->setScene(&m_scene); + + m_anim = new Animation(m_item, "pos"); + m_anim->setEasingCurve(QEasingCurve::OutBounce); + m_ui.easingCurvePicker->setCurrentRow(int(QEasingCurve::OutBounce)); + + startAnimation(); +} + +void Window::createCurveIcons() +{ + QPixmap pix(m_iconSize); + QPainter painter(&pix); + QLinearGradient gradient(0,0, 0, m_iconSize.height()); + gradient.setColorAt(0.0, QColor(240, 240, 240)); + gradient.setColorAt(1.0, QColor(224, 224, 224)); + QBrush brush(gradient); + const QMetaObject &mo = QEasingCurve::staticMetaObject; + QMetaEnum metaEnum = mo.enumerator(mo.indexOfEnumerator("Type")); + // Skip QEasingCurve::Custom + for (int i = 0; i < QEasingCurve::NCurveTypes - 1; ++i) { + painter.fillRect(QRect(QPoint(0, 0), m_iconSize), brush); + QEasingCurve curve((QEasingCurve::Type)i); + painter.setPen(QColor(0, 0, 255, 64)); + qreal xAxis = m_iconSize.height()/1.5; + qreal yAxis = m_iconSize.width()/3; + painter.drawLine(0, xAxis, m_iconSize.width(), xAxis); + painter.drawLine(yAxis, 0, yAxis, m_iconSize.height()); + painter.setPen(Qt::black); + + qreal curveScale = m_iconSize.height()/2; + QPoint currentPos(yAxis, xAxis); + + for (qreal t = 0; t < 1.0; t+=1.0/curveScale) { + QPoint to; + to.setX(yAxis + curveScale * t); + to.setY(xAxis - curveScale * curve.valueForProgress(t)); + painter.drawLine(currentPos, to); + currentPos = to; + } + QListWidgetItem *item = new QListWidgetItem; + item->setIcon(QIcon(pix)); + item->setText(metaEnum.key(i)); + m_ui.easingCurvePicker->addItem(item); + } +} + +void Window::startAnimation() +{ + m_anim->setStartValue(QPointF(0, 0)); + m_anim->setEndValue(QPointF(100, 100)); + m_anim->setDuration(2000); + m_anim->setLoopCount(-1); // forever + m_anim->start(); +} + +void Window::curveChanged(int row) +{ + QEasingCurve::Type curveType = (QEasingCurve::Type)row; + m_anim->setEasingCurve(curveType); + m_anim->setCurrentTime(0); + + bool isElastic = curveType >= QEasingCurve::InElastic && curveType <= QEasingCurve::OutInElastic; + bool isBounce = curveType >= QEasingCurve::InBounce && curveType <= QEasingCurve::OutInBounce; + m_ui.periodSpinBox->setEnabled(isElastic); + m_ui.amplitudeSpinBox->setEnabled(isElastic || isBounce); + m_ui.overshootSpinBox->setEnabled(curveType >= QEasingCurve::InBack && curveType <= QEasingCurve::OutInBack); +} + +void Window::pathChanged(int index) +{ + m_anim->setPathType((Animation::PathType)index); +} + +void Window::periodChanged(double value) +{ + QEasingCurve curve = m_anim->easingCurve(); + curve.setPeriod(value); + m_anim->setEasingCurve(curve); +} + +void Window::amplitudeChanged(double value) +{ + QEasingCurve curve = m_anim->easingCurve(); + curve.setAmplitude(value); + m_anim->setEasingCurve(curve); +} + +void Window::overshootChanged(double value) +{ + QEasingCurve curve = m_anim->easingCurve(); + curve.setOvershoot(value); + m_anim->setEasingCurve(curve); +} + diff --git a/examples/animation/easing/window.h b/examples/animation/easing/window.h new file mode 100644 index 0000000..f3a8cb3 --- /dev/null +++ b/examples/animation/easing/window.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "ui_form.h" +#include "animation.h" + +class PixmapItem : public QObject, public QGraphicsPixmapItem +{ + Q_OBJECT + Q_PROPERTY(QPointF pos READ pos WRITE setPos) +public: + PixmapItem(const QPixmap &pix) : QGraphicsPixmapItem(pix) + { + } +}; + +class Window : public QWidget { + Q_OBJECT +public: + Window(QWidget *parent = 0); +private slots: + void curveChanged(int row); + void pathChanged(int index); + void periodChanged(double); + void amplitudeChanged(double); + void overshootChanged(double); + +private: + void createCurveIcons(); + void startAnimation(); + + Ui::Form m_ui; + QGraphicsScene m_scene; + PixmapItem *m_item; + Animation *m_anim; + QSize m_iconSize; + + +}; diff --git a/examples/animation/moveblocks/main.cpp b/examples/animation/moveblocks/main.cpp new file mode 100644 index 0000000..b00485e --- /dev/null +++ b/examples/animation/moveblocks/main.cpp @@ -0,0 +1,296 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +class StateSwitchEvent: public QEvent +{ +public: + StateSwitchEvent() + : QEvent(Type(StateSwitchType)) + { + } + + StateSwitchEvent(int rand) + : QEvent(Type(StateSwitchType)), + m_rand(rand) + { + } + + enum { StateSwitchType = QEvent::User + 256 }; + + int rand() const { return m_rand; } + +private: + int m_rand; +}; + + +class QGraphicsRectWidget : public QGraphicsWidget +{ +public: + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, + QWidget *) + { + painter->fillRect(rect(), Qt::blue); + } +}; + +class StateSwitchTransition: public QAbstractTransition +{ +public: + StateSwitchTransition(int rand) + : QAbstractTransition(), + m_rand(rand) + { + } + +protected: + virtual bool eventTest(QEvent *event) + { + return (event->type() == QEvent::Type(StateSwitchEvent::StateSwitchType)) + && (static_cast(event)->rand() == m_rand); + } + + virtual void onTransition(QEvent *) {} + +private: + int m_rand; +}; + +class StateSwitcher : public QState +{ + Q_OBJECT +public: + StateSwitcher(QStateMachine *machine) + : QState(machine->rootState()), m_machine(machine), + m_stateCount(0), m_lastIndex(0) + { } + + virtual void onEntry(QEvent *) + { + int n; + while ((n = (qrand() % m_stateCount + 1)) == m_lastIndex) + { } + m_lastIndex = n; + m_machine->postEvent(new StateSwitchEvent(n)); + } + virtual void onExit(QEvent *) {} + + void addState(QState *state, QAbstractAnimation *animation) { + StateSwitchTransition *trans = new StateSwitchTransition(++m_stateCount); + trans->setTargetState(state); + addTransition(trans); + trans->addAnimation(animation); + } + + +private: + QStateMachine *m_machine; + int m_stateCount; + int m_lastIndex; +}; + +QState *createGeometryState(QObject *w1, const QRect &rect1, + QObject *w2, const QRect &rect2, + QObject *w3, const QRect &rect3, + QObject *w4, const QRect &rect4, + QState *parent) +{ + QState *result = new QState(parent); + result->assignProperty(w1, "geometry", rect1); + result->assignProperty(w1, "geometry", rect1); + result->assignProperty(w2, "geometry", rect2); + result->assignProperty(w3, "geometry", rect3); + result->assignProperty(w4, "geometry", rect4); + + return result; +} + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + +#if 0 + QWidget window; + QPalette palette; + palette.setBrush(QPalette::Window, Qt::black); + window.setPalette(palette); + QPushButton *button1 = new QPushButton("A", &window); + QPushButton *button2 = new QPushButton("B", &window); + QPushButton *button3 = new QPushButton("C", &window); + QPushButton *button4 = new QPushButton("D", &window); + + button1->setObjectName("button1"); + button2->setObjectName("button2"); + button3->setObjectName("button3"); + button4->setObjectName("button4"); +#else + QGraphicsRectWidget *button1 = new QGraphicsRectWidget; + QGraphicsRectWidget *button2 = new QGraphicsRectWidget; + QGraphicsRectWidget *button3 = new QGraphicsRectWidget; + QGraphicsRectWidget *button4 = new QGraphicsRectWidget; + button2->setZValue(1); + button3->setZValue(2); + button4->setZValue(3); + QGraphicsScene scene(0, 0, 300, 300); + scene.setBackgroundBrush(Qt::black); + scene.addItem(button1); + scene.addItem(button2); + scene.addItem(button3); + scene.addItem(button4); + + QGraphicsView window(&scene); + window.setFrameStyle(0); + window.setAlignment(Qt::AlignLeft | Qt::AlignTop); + window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); +#endif + QStateMachine machine; + + QState *group = new QState(); + group->setObjectName("group"); + QTimer timer; + timer.setInterval(1250); + timer.setSingleShot(true); + QObject::connect(group, SIGNAL(entered()), &timer, SLOT(start())); + + QState *state1; + QState *state2; + QState *state3; + QState *state4; + QState *state5; + QState *state6; + QState *state7; + + state1 = createGeometryState(button1, QRect(100, 0, 50, 50), + button2, QRect(150, 0, 50, 50), + button3, QRect(200, 0, 50, 50), + button4, QRect(250, 0, 50, 50), + group); + state2 = createGeometryState(button1, QRect(250, 100, 50, 50), + button2, QRect(250, 150, 50, 50), + button3, QRect(250, 200, 50, 50), + button4, QRect(250, 250, 50, 50), + group); + state3 = createGeometryState(button1, QRect(150, 250, 50, 50), + button2, QRect(100, 250, 50, 50), + button3, QRect(50, 250, 50, 50), + button4, QRect(0, 250, 50, 50), + group); + state4 = createGeometryState(button1, QRect(0, 150, 50, 50), + button2, QRect(0, 100, 50, 50), + button3, QRect(0, 50, 50, 50), + button4, QRect(0, 0, 50, 50), + group); + state5 = createGeometryState(button1, QRect(100, 100, 50, 50), + button2, QRect(150, 100, 50, 50), + button3, QRect(100, 150, 50, 50), + button4, QRect(150, 150, 50, 50), + group); + state6 = createGeometryState(button1, QRect(50, 50, 50, 50), + button2, QRect(200, 50, 50, 50), + button3, QRect(50, 200, 50, 50), + button4, QRect(200, 200, 50, 50), + group); + state7 = createGeometryState(button1, QRect(0, 0, 50, 50), + button2, QRect(250, 0, 50, 50), + button3, QRect(0, 250, 50, 50), + button4, QRect(250, 250, 50, 50), + group); + group->setInitialState(state1); + + QParallelAnimationGroup animationGroup; + QSequentialAnimationGroup *subGroup; + + QPropertyAnimation *anim = new QPropertyAnimation(button4, "geometry"); + anim->setDuration(1000); + anim->setEasingCurve(QEasingCurve::OutElastic); + animationGroup.addAnimation(anim); + + subGroup = new QSequentialAnimationGroup(&animationGroup); + subGroup->addPause(100); + anim = new QPropertyAnimation(button3, "geometry"); + anim->setDuration(1000); + anim->setEasingCurve(QEasingCurve::OutElastic); + subGroup->addAnimation(anim); + + subGroup = new QSequentialAnimationGroup(&animationGroup); + subGroup->addPause(150); + anim = new QPropertyAnimation(button2, "geometry"); + anim->setDuration(1000); + anim->setEasingCurve(QEasingCurve::OutElastic); + subGroup->addAnimation(anim); + + subGroup = new QSequentialAnimationGroup(&animationGroup); + subGroup->addPause(200); + anim = new QPropertyAnimation(button1, "geometry"); + anim->setDuration(1000); + anim->setEasingCurve(QEasingCurve::OutElastic); + subGroup->addAnimation(anim); + + StateSwitcher *stateSwitcher = new StateSwitcher(&machine); + stateSwitcher->setObjectName("stateSwitcher"); + group->addTransition(&timer, SIGNAL(timeout()), stateSwitcher); + stateSwitcher->addState(state1, &animationGroup); + stateSwitcher->addState(state2, &animationGroup); + stateSwitcher->addState(state3, &animationGroup); + stateSwitcher->addState(state4, &animationGroup); + stateSwitcher->addState(state5, &animationGroup); + stateSwitcher->addState(state6, &animationGroup); + stateSwitcher->addState(state7, &animationGroup); + + machine.addState(group); + machine.setInitialState(group); + machine.start(); + + + window.resize(300, 300); + window.show(); + + qsrand(time(0)); + + return app.exec(); +} + +#include "main.moc" diff --git a/examples/animation/moveblocks/moveblocks.pro b/examples/animation/moveblocks/moveblocks.pro new file mode 100644 index 0000000..b8e88b2 --- /dev/null +++ b/examples/animation/moveblocks/moveblocks.pro @@ -0,0 +1,7 @@ +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/moveblocks +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS moveblocks.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/moveblocks +INSTALLS += target sources diff --git a/examples/animation/states/accessories-dictionary.png b/examples/animation/states/accessories-dictionary.png new file mode 100644 index 0000000..e9bd55d Binary files /dev/null and b/examples/animation/states/accessories-dictionary.png differ diff --git a/examples/animation/states/akregator.png b/examples/animation/states/akregator.png new file mode 100644 index 0000000..a086f45 Binary files /dev/null and b/examples/animation/states/akregator.png differ diff --git a/examples/animation/states/digikam.png b/examples/animation/states/digikam.png new file mode 100644 index 0000000..9de9fb2 Binary files /dev/null and b/examples/animation/states/digikam.png differ diff --git a/examples/animation/states/help-browser.png b/examples/animation/states/help-browser.png new file mode 100644 index 0000000..db92faa Binary files /dev/null and b/examples/animation/states/help-browser.png differ diff --git a/examples/animation/states/k3b.png b/examples/animation/states/k3b.png new file mode 100644 index 0000000..bbcafcf Binary files /dev/null and b/examples/animation/states/k3b.png differ diff --git a/examples/animation/states/kchart.png b/examples/animation/states/kchart.png new file mode 100644 index 0000000..1dd115b Binary files /dev/null and b/examples/animation/states/kchart.png differ diff --git a/examples/animation/states/main.cpp b/examples/animation/states/main.cpp new file mode 100644 index 0000000..17a7a8e --- /dev/null +++ b/examples/animation/states/main.cpp @@ -0,0 +1,284 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +class Pixmap : public QGraphicsWidget +{ + Q_OBJECT +public: + Pixmap(const QPixmap &pix) : QGraphicsWidget(), p(pix) + { + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + { + painter->drawPixmap(QPointF(), p); + } + +protected: + QSizeF sizeHint(Qt::SizeHint, const QSizeF & = QSizeF()) + { + return QSizeF(p.width(), p.height()); + } + +private: + QPixmap p; +}; + +int main(int argc, char *argv[]) +{ + Q_INIT_RESOURCE(states); + + QApplication app(argc, argv); + + // Text edit and button + QTextEdit *edit = new QTextEdit; + edit->setText("asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " + "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " + "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " + "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy!"); + + QPushButton *button = new QPushButton; + QGraphicsProxyWidget *buttonProxy = new QGraphicsProxyWidget; + buttonProxy->setWidget(button); + QGraphicsProxyWidget *editProxy = new QGraphicsProxyWidget; + editProxy->setWidget(edit); + + QGroupBox *box = new QGroupBox; + box->setFlat(true); + box->setTitle("Options"); + + QVBoxLayout *layout2 = new QVBoxLayout; + box->setLayout(layout2); + layout2->addWidget(new QRadioButton("Herring")); + layout2->addWidget(new QRadioButton("Blue Parrot")); + layout2->addWidget(new QRadioButton("Petunias")); + layout2->addStretch(); + + QGraphicsProxyWidget *boxProxy = new QGraphicsProxyWidget; + boxProxy->setWidget(box); + + // Parent widget + QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, widget); + layout->addItem(editProxy); + layout->addItem(buttonProxy); + widget->setLayout(layout); + + Pixmap *p1 = new Pixmap(QPixmap(":/digikam.png")); + Pixmap *p2 = new Pixmap(QPixmap(":/akregator.png")); + Pixmap *p3 = new Pixmap(QPixmap(":/accessories-dictionary.png")); + Pixmap *p4 = new Pixmap(QPixmap(":/k3b.png")); + Pixmap *p5 = new Pixmap(QPixmap(":/help-browser.png")); + Pixmap *p6 = new Pixmap(QPixmap(":/kchart.png")); + + QGraphicsScene scene(0, 0, 400, 300); + scene.setBackgroundBrush(scene.palette().window()); + scene.addItem(widget); + scene.addItem(boxProxy); + scene.addItem(p1); + scene.addItem(p2); + scene.addItem(p3); + scene.addItem(p4); + scene.addItem(p5); + scene.addItem(p6); + + QStateMachine machine; + QState *root = machine.rootState(); + QState *state1 = new QState(root); + QState *state2 = new QState(root); + QState *state3 = new QState(root); + machine.setInitialState(state1); + + // State 1 + state1->assignProperty(button, "text", "Switch to state 2"); + state1->assignProperty(widget, "geometry", QRectF(0, 0, 400, 150)); + state1->assignProperty(box, "geometry", QRect(-200, 150, 200, 150)); + state1->assignProperty(p1, "geometry", QRectF(68, 185, 64, 64)); + state1->assignProperty(p2, "geometry", QRectF(168, 185, 64, 64)); + state1->assignProperty(p3, "geometry", QRectF(268, 185, 64, 64)); + state1->assignProperty(p4, "geometry", QRectF(68-150, 48-150, 64, 64)); + state1->assignProperty(p5, "geometry", QRectF(168, 48-150, 64, 64)); + state1->assignProperty(p6, "geometry", QRectF(268+150, 48-150, 64, 64)); + state1->assignProperty(p1, "zRotation", qreal(0)); + state1->assignProperty(p2, "zRotation", qreal(0)); + state1->assignProperty(p3, "zRotation", qreal(0)); + state1->assignProperty(p4, "zRotation", qreal(-270)); + state1->assignProperty(p5, "zRotation", qreal(-90)); + state1->assignProperty(p6, "zRotation", qreal(270)); + state1->assignProperty(boxProxy, "opacity", qreal(0)); + state1->assignProperty(p1, "opacity", qreal(1)); + state1->assignProperty(p2, "opacity", qreal(1)); + state1->assignProperty(p3, "opacity", qreal(1)); + state1->assignProperty(p4, "opacity", qreal(0)); + state1->assignProperty(p5, "opacity", qreal(0)); + state1->assignProperty(p6, "opacity", qreal(0)); + + // State 2 + state2->assignProperty(button, "text", "Switch to state 3"); + state2->assignProperty(widget, "geometry", QRectF(200, 150, 200, 150)); + state2->assignProperty(box, "geometry", QRect(9, 150, 190, 150)); + state2->assignProperty(p1, "geometry", QRectF(68-150, 185+150, 64, 64)); + state2->assignProperty(p2, "geometry", QRectF(168, 185+150, 64, 64)); + state2->assignProperty(p3, "geometry", QRectF(268+150, 185+150, 64, 64)); + state2->assignProperty(p4, "geometry", QRectF(64, 48, 64, 64)); + state2->assignProperty(p5, "geometry", QRectF(168, 48, 64, 64)); + state2->assignProperty(p6, "geometry", QRectF(268, 48, 64, 64)); + state2->assignProperty(p1, "zRotation", qreal(-270)); + state2->assignProperty(p2, "zRotation", qreal(90)); + state2->assignProperty(p3, "zRotation", qreal(270)); + state2->assignProperty(p4, "zRotation", qreal(0)); + state2->assignProperty(p5, "zRotation", qreal(0)); + state2->assignProperty(p6, "zRotation", qreal(0)); + state2->assignProperty(boxProxy, "opacity", qreal(1)); + state2->assignProperty(p1, "opacity", qreal(0)); + state2->assignProperty(p2, "opacity", qreal(0)); + state2->assignProperty(p3, "opacity", qreal(0)); + state2->assignProperty(p4, "opacity", qreal(1)); + state2->assignProperty(p5, "opacity", qreal(1)); + state2->assignProperty(p6, "opacity", qreal(1)); + + // State 3 + state3->assignProperty(button, "text", "Switch to state 1"); + state3->assignProperty(p1, "geometry", QRectF(5, 5, 64, 64)); + state3->assignProperty(p2, "geometry", QRectF(5, 5 + 64 + 5, 64, 64)); + state3->assignProperty(p3, "geometry", QRectF(5, 5 + (64 + 5) + 64, 64, 64)); + state3->assignProperty(p4, "geometry", QRectF(5 + 64 + 5, 5, 64, 64)); + state3->assignProperty(p5, "geometry", QRectF(5 + 64 + 5, 5 + 64 + 5, 64, 64)); + state3->assignProperty(p6, "geometry", QRectF(5 + 64 + 5, 5 + (64 + 5) + 64, 64, 64)); + state3->assignProperty(widget, "geometry", QRectF(138, 5, 400 - 138, 200)); + state3->assignProperty(box, "geometry", QRect(5, 205, 400, 90)); + state3->assignProperty(p1, "opacity", qreal(1)); + state3->assignProperty(p2, "opacity", qreal(1)); + state3->assignProperty(p3, "opacity", qreal(1)); + state3->assignProperty(p4, "opacity", qreal(1)); + state3->assignProperty(p5, "opacity", qreal(1)); + state3->assignProperty(p6, "opacity", qreal(1)); + + QParallelAnimationGroup animation1; + + QSequentialAnimationGroup *animation1SubGroup; + animation1SubGroup = new QSequentialAnimationGroup(&animation1); + animation1SubGroup->addPause(250); + animation1SubGroup->addAnimation(new QPropertyAnimation(box, "geometry")); + + animation1.addAnimation(new QPropertyAnimation(widget, "geometry")); + animation1.addAnimation(new QPropertyAnimation(p1, "geometry")); + animation1.addAnimation(new QPropertyAnimation(p2, "geometry")); + animation1.addAnimation(new QPropertyAnimation(p3, "geometry")); + animation1.addAnimation(new QPropertyAnimation(p4, "geometry")); + animation1.addAnimation(new QPropertyAnimation(p5, "geometry")); + animation1.addAnimation(new QPropertyAnimation(p6, "geometry")); + animation1.addAnimation(new QPropertyAnimation(p1, "zRotation")); + animation1.addAnimation(new QPropertyAnimation(p2, "zRotation")); + animation1.addAnimation(new QPropertyAnimation(p3, "zRotation")); + animation1.addAnimation(new QPropertyAnimation(p4, "zRotation")); + animation1.addAnimation(new QPropertyAnimation(p5, "zRotation")); + animation1.addAnimation(new QPropertyAnimation(p6, "zRotation")); + animation1.addAnimation(new QPropertyAnimation(p1, "opacity")); + animation1.addAnimation(new QPropertyAnimation(p2, "opacity")); + animation1.addAnimation(new QPropertyAnimation(p3, "opacity")); + animation1.addAnimation(new QPropertyAnimation(p4, "opacity")); + animation1.addAnimation(new QPropertyAnimation(p5, "opacity")); + animation1.addAnimation(new QPropertyAnimation(p6, "opacity")); + + QParallelAnimationGroup animation2; + animation2.addAnimation(new QPropertyAnimation(box, "geometry")); + animation2.addAnimation(new QPropertyAnimation(widget, "geometry")); + animation2.addAnimation(new QPropertyAnimation(p1, "geometry")); + animation2.addAnimation(new QPropertyAnimation(p2, "geometry")); + animation2.addAnimation(new QPropertyAnimation(p3, "geometry")); + animation2.addAnimation(new QPropertyAnimation(p4, "geometry")); + animation2.addAnimation(new QPropertyAnimation(p5, "geometry")); + animation2.addAnimation(new QPropertyAnimation(p6, "geometry")); + animation2.addAnimation(new QPropertyAnimation(p1, "zRotation")); + animation2.addAnimation(new QPropertyAnimation(p2, "zRotation")); + animation2.addAnimation(new QPropertyAnimation(p3, "zRotation")); + animation2.addAnimation(new QPropertyAnimation(p4, "zRotation")); + animation2.addAnimation(new QPropertyAnimation(p5, "zRotation")); + animation2.addAnimation(new QPropertyAnimation(p6, "zRotation")); + animation2.addAnimation(new QPropertyAnimation(p1, "opacity")); + animation2.addAnimation(new QPropertyAnimation(p2, "opacity")); + animation2.addAnimation(new QPropertyAnimation(p3, "opacity")); + animation2.addAnimation(new QPropertyAnimation(p4, "opacity")); + animation2.addAnimation(new QPropertyAnimation(p5, "opacity")); + animation2.addAnimation(new QPropertyAnimation(p6, "opacity")); + + QParallelAnimationGroup animation3; + animation3.addAnimation(new QPropertyAnimation(box, "geometry")); + animation3.addAnimation(new QPropertyAnimation(widget, "geometry")); + animation3.addAnimation(new QPropertyAnimation(p1, "geometry")); + animation3.addAnimation(new QPropertyAnimation(p2, "geometry")); + animation3.addAnimation(new QPropertyAnimation(p3, "geometry")); + animation3.addAnimation(new QPropertyAnimation(p4, "geometry")); + animation3.addAnimation(new QPropertyAnimation(p5, "geometry")); + animation3.addAnimation(new QPropertyAnimation(p6, "geometry")); + animation3.addAnimation(new QPropertyAnimation(p1, "zRotation")); + animation3.addAnimation(new QPropertyAnimation(p2, "zRotation")); + animation3.addAnimation(new QPropertyAnimation(p3, "zRotation")); + animation3.addAnimation(new QPropertyAnimation(p4, "zRotation")); + animation3.addAnimation(new QPropertyAnimation(p5, "zRotation")); + animation3.addAnimation(new QPropertyAnimation(p6, "zRotation")); + animation3.addAnimation(new QPropertyAnimation(p1, "opacity")); + animation3.addAnimation(new QPropertyAnimation(p2, "opacity")); + animation3.addAnimation(new QPropertyAnimation(p3, "opacity")); + animation3.addAnimation(new QPropertyAnimation(p4, "opacity")); + animation3.addAnimation(new QPropertyAnimation(p5, "opacity")); + animation3.addAnimation(new QPropertyAnimation(p6, "opacity")); + + QAbstractTransition *t1 = state1->addTransition(button, SIGNAL(clicked()), state2); + t1->addAnimation(&animation1); + QAbstractTransition *t2 = state2->addTransition(button, SIGNAL(clicked()), state3); + t2->addAnimation(&animation2); + QAbstractTransition *t3 = state3->addTransition(button, SIGNAL(clicked()), state1); + t3->addAnimation(&animation3); + + machine.start(); + + QGraphicsView view(&scene); + view.show(); + + return app.exec(); +} + +#include "main.moc" diff --git a/examples/animation/states/states.pro b/examples/animation/states/states.pro new file mode 100644 index 0000000..f4d1e0b --- /dev/null +++ b/examples/animation/states/states.pro @@ -0,0 +1,8 @@ +SOURCES += main.cpp +RESOURCES += states.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/states +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS states.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/states +INSTALLS += target sources diff --git a/examples/animation/states/states.qrc b/examples/animation/states/states.qrc new file mode 100644 index 0000000..60ab3f7 --- /dev/null +++ b/examples/animation/states/states.qrc @@ -0,0 +1,10 @@ + + + accessories-dictionary.png + akregator.png + digikam.png + help-browser.png + k3b.png + kchart.png + + diff --git a/examples/animation/stickman/animation.cpp b/examples/animation/stickman/animation.cpp new file mode 100644 index 0000000..c2c6bd1 --- /dev/null +++ b/examples/animation/stickman/animation.cpp @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "animation.h" + +#include +#include +#include + +class Frame +{ +public: + Frame() { + } + + int nodeCount() const + { + return m_nodePositions.size(); + } + + void setNodeCount(int nodeCount) + { + while (nodeCount > m_nodePositions.size()) + m_nodePositions.append(QPointF()); + + while (nodeCount < m_nodePositions.size()) + m_nodePositions.removeLast(); + } + + QPointF nodePos(int idx) const + { + return m_nodePositions.at(idx); + } + + void setNodePos(int idx, const QPointF &pos) + { + m_nodePositions[idx] = pos; + } + +private: + QList m_nodePositions; +}; + +Animation::Animation() +{ + m_currentFrame = 0; + m_frames.append(new Frame); +} + +Animation::~Animation() +{ + qDeleteAll(m_frames); +} + +void Animation::setTotalFrames(int totalFrames) +{ + while (m_frames.size() < totalFrames) + m_frames.append(new Frame); + + while (totalFrames < m_frames.size()) + delete m_frames.takeLast(); +} + +int Animation::totalFrames() const +{ + return m_frames.size(); +} + +void Animation::setCurrentFrame(int currentFrame) +{ + m_currentFrame = qMax(qMin(currentFrame, totalFrames()-1), 0); +} + +int Animation::currentFrame() const +{ + return m_currentFrame; +} + +void Animation::setNodeCount(int nodeCount) +{ + Frame *frame = m_frames.at(m_currentFrame); + frame->setNodeCount(nodeCount); +} + +int Animation::nodeCount() const +{ + Frame *frame = m_frames.at(m_currentFrame); + return frame->nodeCount(); +} + +void Animation::setNodePos(int idx, const QPointF &pos) +{ + Frame *frame = m_frames.at(m_currentFrame); + frame->setNodePos(idx, pos); +} + +QPointF Animation::nodePos(int idx) const +{ + Frame *frame = m_frames.at(m_currentFrame); + return frame->nodePos(idx); +} + +QString Animation::name() const +{ + return m_name; +} + +void Animation::setName(const QString &name) +{ + m_name = name; +} + +void Animation::save(QIODevice *device) const +{ + QDataStream stream(device); + stream << m_name; + stream << m_frames.size(); + foreach (Frame *frame, m_frames) { + stream << frame->nodeCount(); + for (int i=0; inodeCount(); ++i) + stream << frame->nodePos(i); + } +} + +void Animation::load(QIODevice *device) +{ + if (!m_frames.isEmpty()) + qDeleteAll(m_frames); + + m_frames.clear(); + + QDataStream stream(device); + stream >> m_name; + + int frameCount; + stream >> frameCount; + + for (int i=0; i> nodeCount; + + Frame *frame = new Frame; + frame->setNodeCount(nodeCount); + + for (int j=0; j> pos; + + frame->setNodePos(j, pos); + } + + m_frames.append(frame); + } +} diff --git a/examples/animation/stickman/animation.h b/examples/animation/stickman/animation.h new file mode 100644 index 0000000..b0b39c9 --- /dev/null +++ b/examples/animation/stickman/animation.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANIMATION_H +#define ANIMATION_H + +#include +#include +#include + +class Frame; +QT_BEGIN_NAMESPACE +class QIODevice; +QT_END_NAMESPACE +class Animation +{ +public: + Animation(); + ~Animation(); + + void setTotalFrames(int totalFrames); + int totalFrames() const; + + void setCurrentFrame(int currentFrame); + int currentFrame() const; + + void setNodeCount(int nodeCount); + int nodeCount() const; + + void setNodePos(int idx, const QPointF &pos); + QPointF nodePos(int idx) const; + + QString name() const; + void setName(const QString &name); + + void save(QIODevice *device) const; + void load(QIODevice *device); + +private: + QString m_name; + QList m_frames; + int m_currentFrame; +}; + +#endif diff --git a/examples/animation/stickman/animations/chilling b/examples/animation/stickman/animations/chilling new file mode 100644 index 0000000..a81fc7a Binary files /dev/null and b/examples/animation/stickman/animations/chilling differ diff --git a/examples/animation/stickman/animations/dancing b/examples/animation/stickman/animations/dancing new file mode 100644 index 0000000..462f66f Binary files /dev/null and b/examples/animation/stickman/animations/dancing differ diff --git a/examples/animation/stickman/animations/dead b/examples/animation/stickman/animations/dead new file mode 100644 index 0000000..9859b4b Binary files /dev/null and b/examples/animation/stickman/animations/dead differ diff --git a/examples/animation/stickman/animations/jumping b/examples/animation/stickman/animations/jumping new file mode 100644 index 0000000..12661a1 Binary files /dev/null and b/examples/animation/stickman/animations/jumping differ diff --git a/examples/animation/stickman/editor/animationdialog.cpp b/examples/animation/stickman/editor/animationdialog.cpp new file mode 100644 index 0000000..441517d --- /dev/null +++ b/examples/animation/stickman/editor/animationdialog.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "animationdialog.h" +#include "stickman.h" +#include "animation.h" +#include "node.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +AnimationDialog::AnimationDialog(StickMan *stickman, QWidget *parent) + : QDialog(parent), m_animation(0), m_stickman(stickman) +{ + initUi(); +} + +AnimationDialog::~AnimationDialog() +{ + delete m_animation; +} + +void AnimationDialog::initUi() +{ + setWindowTitle("Animation"); + setEnabled(false); + + // Second page + m_currentFrame = new QSpinBox(); + m_totalFrames = new QSpinBox(); + m_name = new QLineEdit(); + + connect(m_currentFrame, SIGNAL(valueChanged(int)), this, SLOT(currentFrameChanged(int))); + connect(m_totalFrames, SIGNAL(valueChanged(int)), this, SLOT(totalFramesChanged(int))); + connect(m_name, SIGNAL(textChanged(QString)), this, SLOT(setCurrentAnimationName(QString))); + + QGridLayout *gridLayout = new QGridLayout(this); + gridLayout->addWidget(new QLabel("Name:"), 0, 0, 1, 2); + gridLayout->addWidget(m_name, 0, 2, 1, 2); + gridLayout->addWidget(new QLabel("Frame:"), 1, 0); + gridLayout->addWidget(m_currentFrame, 1, 1); + gridLayout->addWidget(new QLabel("of total # of frames: "), 1, 2); + gridLayout->addWidget(m_totalFrames, 1, 3); +} + +void AnimationDialog::initFromAnimation() +{ + m_currentFrame->setRange(0, m_animation->totalFrames()-1); + m_currentFrame->setValue(m_animation->currentFrame()); + + m_totalFrames->setRange(1, 1000); + m_totalFrames->setValue(m_animation->totalFrames()); + + m_name->setText(m_animation->name()); +} + +void AnimationDialog::saveAnimation() +{ + saveCurrentFrame(); + + QString fileName = QFileDialog::getSaveFileName(this, "Save animation"); + + QFile file(fileName); + if (file.open(QIODevice::WriteOnly)) + m_animation->save(&file); +} + +void AnimationDialog::loadAnimation() +{ + if (maybeSave() != QMessageBox::Cancel) { + QString fileName = QFileDialog::getOpenFileName(this, "Open animation"); + + QFile file(fileName); + if (file.open(QIODevice::ReadOnly)) { + if (m_animation == 0) + newAnimation(); + + m_animation->load(&file); + stickManFromCurrentFrame(); + initFromAnimation(); + } + } +} + +QMessageBox::StandardButton AnimationDialog::maybeSave() +{ + if (m_animation == 0) + return QMessageBox::No; + + QMessageBox::StandardButton button = QMessageBox::question(this, "Save?", "Do you want to save your changes?", + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + if (button == QMessageBox::Save) + saveAnimation(); + + return button; +} + +void AnimationDialog::newAnimation() +{ + if (maybeSave() != QMessageBox::Cancel) { + setEnabled(true); + delete m_animation; + m_animation = new Animation(); + initFromAnimation(); + } +} + +// Gets the data from the stickman and stores it in current frame +void AnimationDialog::saveCurrentFrame() +{ + int count = m_stickman->nodeCount(); + m_animation->setNodeCount(count); + for (int i=0; inode(i); + m_animation->setNodePos(i, node->pos()); + } +} + +// Gets the data from the current frame and sets the stickman +void AnimationDialog::stickManFromCurrentFrame() +{ + int count = m_animation->nodeCount(); + for (int i=0;inode(i); + node->setPos(m_animation->nodePos(i)); + } +} + +void AnimationDialog::currentFrameChanged(int currentFrame) +{ + saveCurrentFrame(); + qDebug("currentFrame: %d", currentFrame); + m_animation->setCurrentFrame(currentFrame); + stickManFromCurrentFrame(); + initFromAnimation(); +} + +void AnimationDialog::totalFramesChanged(int totalFrames) +{ + m_animation->setTotalFrames(totalFrames); + stickManFromCurrentFrame(); + initFromAnimation(); +} + +void AnimationDialog::setCurrentAnimationName(const QString &name) +{ + m_animation->setName(name); +} diff --git a/examples/animation/stickman/editor/animationdialog.h b/examples/animation/stickman/editor/animationdialog.h new file mode 100644 index 0000000..6025088 --- /dev/null +++ b/examples/animation/stickman/editor/animationdialog.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANIMATIONDIALOG_H +#define ANIMATIONDIALOG_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QSpinBox; +class QLineEdit; +QT_END_NAMESPACE +class StickMan; +class Animation; +class AnimationDialog: public QDialog +{ + Q_OBJECT +public: + AnimationDialog(StickMan *stickMan, QWidget *parent = 0); + ~AnimationDialog(); + +public slots: + void currentFrameChanged(int currentFrame); + void totalFramesChanged(int totalFrames); + void setCurrentAnimationName(const QString &name); + + void newAnimation(); + void saveAnimation(); + void loadAnimation(); + +private: + void saveCurrentFrame(); + void stickManFromCurrentFrame(); + void initFromAnimation(); + void initUi(); + QMessageBox::StandardButton maybeSave(); + + QSpinBox *m_currentFrame; + QSpinBox *m_totalFrames; + QLineEdit *m_name; + Animation *m_animation; + StickMan *m_stickman; +}; + +#endif diff --git a/examples/animation/stickman/editor/editor.pri b/examples/animation/stickman/editor/editor.pri new file mode 100644 index 0000000..7ad9edb --- /dev/null +++ b/examples/animation/stickman/editor/editor.pri @@ -0,0 +1,2 @@ +SOURCES += $$PWD/animationdialog.cpp $$PWD/mainwindow.cpp +HEADERS += $$PWD/animationdialog.h $$PWD/mainwindow.h diff --git a/examples/animation/stickman/editor/mainwindow.cpp b/examples/animation/stickman/editor/mainwindow.cpp new file mode 100644 index 0000000..c6464c6 --- /dev/null +++ b/examples/animation/stickman/editor/mainwindow.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include "animationdialog.h" +#include "stickman.h" + +#include +#include + +MainWindow::MainWindow(StickMan *stickMan) +{ + initActions(stickMan); +} + +MainWindow::~MainWindow() +{ +} + +void MainWindow::initActions(StickMan *stickMan) +{ + AnimationDialog *dialog = new AnimationDialog(stickMan, this); + dialog->show(); + + QMenu *fileMenu = menuBar()->addMenu("&File"); + QAction *loadAction = fileMenu->addAction("&Open"); + QAction *saveAction = fileMenu->addAction("&Save"); + QAction *exitAction = fileMenu->addAction("E&xit"); + + QMenu *animationMenu = menuBar()->addMenu("&Animation"); + QAction *newAnimationAction = animationMenu->addAction("&New animation"); + + connect(loadAction, SIGNAL(triggered()), dialog, SLOT(loadAnimation())); + connect(saveAction, SIGNAL(triggered()), dialog, SLOT(saveAnimation())); + connect(exitAction, SIGNAL(triggered()), QApplication::instance(), SLOT(quit())); + connect(newAnimationAction, SIGNAL(triggered()), dialog, SLOT(newAnimation())); + +} diff --git a/examples/animation/stickman/editor/mainwindow.h b/examples/animation/stickman/editor/mainwindow.h new file mode 100644 index 0000000..4c2b949 --- /dev/null +++ b/examples/animation/stickman/editor/mainwindow.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class StickMan; +class MainWindow: public QMainWindow +{ +public: + MainWindow(StickMan *stickMan); + ~MainWindow(); + +private: + void initActions(StickMan *stickMan); +}; + +#endif diff --git a/examples/animation/stickman/graphicsview.cpp b/examples/animation/stickman/graphicsview.cpp new file mode 100644 index 0000000..754f3bc --- /dev/null +++ b/examples/animation/stickman/graphicsview.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "graphicsview.h" +#include "editor/mainwindow.h" +#include "stickman.h" + +#include +#include +#include + +GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent), m_editor(0) {} + +void GraphicsView::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Escape) + close(); + +#if 0 + if (e->key() == Qt::Key_F1) { + if (m_editor == 0) { + QGraphicsScene *scene = new QGraphicsScene; + StickMan *stickMan = new StickMan; + stickMan->setDrawSticks(true); + scene->addItem(stickMan); + + QGraphicsView *view = new QGraphicsView; + view->setBackgroundBrush(Qt::black); + view->setRenderHints(QPainter::Antialiasing); + view->setScene(scene); + + m_editor = new MainWindow(stickMan); + m_editor->setCentralWidget(view); + } + + m_editor->showMaximized(); + } +#endif + + emit keyPressed(Qt::Key(e->key())); +} + + diff --git a/examples/animation/stickman/graphicsview.h b/examples/animation/stickman/graphicsview.h new file mode 100644 index 0000000..2515418 --- /dev/null +++ b/examples/animation/stickman/graphicsview.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GRAPHICSVIEW_H +#define GRAPHICSVIEW + +#include + +class MainWindow; +class GraphicsView: public QGraphicsView +{ + Q_OBJECT +public: + GraphicsView(QWidget *parent = 0); + +protected: + void keyPressEvent(QKeyEvent *); + +signals: + void keyPressed(int key); + +private: + MainWindow *m_editor; +}; + +#endif diff --git a/examples/animation/stickman/lifecycle.cpp b/examples/animation/stickman/lifecycle.cpp new file mode 100644 index 0000000..eb4ed11 --- /dev/null +++ b/examples/animation/stickman/lifecycle.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "lifecycle.h" +#include "stickman.h" +#include "node.h" +#include "animation.h" +#include "graphicsview.h" + +#include +#include + +class KeyPressTransition: public QSignalTransition +{ +public: + KeyPressTransition(GraphicsView *receiver, Qt::Key key) + : QSignalTransition(receiver, SIGNAL(keyPressed(int))), m_key(key) + { + } + KeyPressTransition(GraphicsView *receiver, Qt::Key key, QAbstractState *target) + : QSignalTransition(receiver, SIGNAL(keyPressed(int)), QList() << target), m_key(key) + { + } + + virtual bool eventTest(QEvent *e) + { + if (QSignalTransition::eventTest(e)) { + QVariant key = static_cast(e)->arguments().at(0); + return (key.toInt() == int(m_key)); + } + + return false; + } +private: + Qt::Key m_key; +}; + +//! [4] +class LightningStrikesTransition: public QEventTransition +{ +public: + LightningStrikesTransition(QAbstractState *target) + : QEventTransition(this, QEvent::Timer, QList() << target) + { + qsrand((uint)QDateTime::currentDateTime().toTime_t()); + startTimer(1000); + } + + virtual bool eventTest(QEvent *e) + { + return QEventTransition::eventTest(e) && ((qrand() % 50) == 0); + } +}; +//! [4] + +LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) + : m_stickMan(stickMan), m_keyReceiver(keyReceiver) +{ + // Create animation group to be used for all transitions + m_animationGroup = new QParallelAnimationGroup(); + const int stickManNodeCount = m_stickMan->nodeCount(); + for (int i=0; inode(i), "position"); + m_animationGroup->addAnimation(pa); + } + + // Set up intial state graph +//! [3] + m_machine = new QStateMachine(); + m_machine->addDefaultAnimation(m_animationGroup); +//! [3] + + m_alive = new QState(m_machine->rootState()); + m_alive->setObjectName("alive"); + + // Make it blink when lightning strikes before entering dead animation + QState *lightningBlink = new QState(m_machine->rootState()); + lightningBlink->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::white); + lightningBlink->assignProperty(m_stickMan, "penColor", Qt::black); + lightningBlink->assignProperty(m_stickMan, "fillColor", Qt::white); + lightningBlink->assignProperty(m_stickMan, "isDead", true); + +//! [5] + QTimer *timer = new QTimer(lightningBlink); + timer->setSingleShot(true); + timer->setInterval(100); + QObject::connect(lightningBlink, SIGNAL(entered()), timer, SLOT(start())); + QObject::connect(lightningBlink, SIGNAL(exited()), timer, SLOT(stop())); +//! [5] + + m_dead = new QState(m_machine->rootState()); + m_dead->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::black); + m_dead->assignProperty(m_stickMan, "penColor", Qt::white); + m_dead->assignProperty(m_stickMan, "fillColor", Qt::black); + m_dead->setObjectName("dead"); + + // Idle state (sets no properties) + m_idle = new QState(m_alive); + m_idle->setObjectName("idle"); + + m_alive->setInitialState(m_idle); + + // Lightning strikes at random + m_alive->addTransition(new LightningStrikesTransition(lightningBlink)); +//! [0] + lightningBlink->addTransition(timer, SIGNAL(timeout()), m_dead); +//! [0] + + m_machine->setInitialState(m_alive); +} + +void LifeCycle::setDeathAnimation(const QString &fileName) +{ + QState *deathAnimation = makeState(m_dead, fileName); + m_dead->setInitialState(deathAnimation); +} + +void LifeCycle::start() +{ + m_machine->start(); +} + +void LifeCycle::addActivity(const QString &fileName, Qt::Key key) +{ + QState *state = makeState(m_alive, fileName); + m_alive->addTransition(new KeyPressTransition(m_keyReceiver, key, state)); +} + +QState *LifeCycle::makeState(QState *parentState, const QString &animationFileName) +{ + QState *topLevel = new QState(parentState); + + Animation animation; + { + QFile file(animationFileName); + if (file.open(QIODevice::ReadOnly)) + animation.load(&file); + } + + const int frameCount = animation.totalFrames(); + QState *previousState = 0; + for (int i=0; iassignProperty(m_stickMan->node(j), "position", animation.nodePos(j)); +//! [1] + + frameState->setObjectName(QString::fromLatin1("frame %0").arg(i)); + if (previousState == 0) + topLevel->setInitialState(frameState); + else +//! [2] + previousState->addTransition(previousState, SIGNAL(polished()), frameState); +//! [2] + + previousState = frameState; + } + + // Loop + previousState->addTransition(previousState, SIGNAL(polished()), topLevel->initialState()); + + return topLevel; + +} + +LifeCycle::~LifeCycle() +{ + delete m_machine; + delete m_animationGroup; +} diff --git a/examples/animation/stickman/lifecycle.h b/examples/animation/stickman/lifecycle.h new file mode 100644 index 0000000..2be4762 --- /dev/null +++ b/examples/animation/stickman/lifecycle.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LIFECYCLE_H +#define LIFECYCLE_H + +#include + +class StickMan; +QT_BEGIN_NAMESPACE +class QStateMachine; +class QAnimationGroup; +class QState; +class QAbstractState; +class QAbstractTransition; +QT_END_NAMESPACE +class GraphicsView; +class LifeCycle +{ +public: + LifeCycle(StickMan *stickMan, GraphicsView *keyEventReceiver); + ~LifeCycle(); + + void setDeathAnimation(const QString &fileName); + void addActivity(const QString &fileName, Qt::Key key); + + void start(); + +private: + QState *makeState(QState *parentState, const QString &animationFileName); + + StickMan *m_stickMan; + QStateMachine *m_machine; + QAnimationGroup *m_animationGroup; + GraphicsView *m_keyReceiver; + + QState *m_alive; + QState *m_dead; + QState *m_idle; +}; + +#endif diff --git a/examples/animation/stickman/main.cpp b/examples/animation/stickman/main.cpp new file mode 100644 index 0000000..62d8252 --- /dev/null +++ b/examples/animation/stickman/main.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "animation.h" +#include "node.h" +#include "lifecycle.h" +#include "stickman.h" +#include "graphicsview.h" + +#include +#include + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + StickMan *stickMan = new StickMan; + stickMan->setDrawSticks(false); + + QGraphicsTextItem *textItem = new QGraphicsTextItem(); + textItem->setHtml("Stickman" + "

" + "Tell the stickman what to do!" + "

" + "

" + "

  • Press J to make the stickman jump.
  • " + "
  • Press D to make the stickman dance.
  • " + "
  • Press C to make him chill out.
  • " + "
  • When you are done, press Escape.
  • " + "

    " + "

    If he is unlucky, the stickman will get struck by lightning, and never jump, dance or chill out again." + "

    "); + qreal w = textItem->boundingRect().width(); + QRectF stickManBoundingRect = stickMan->mapToScene(stickMan->boundingRect()).boundingRect(); + textItem->setPos(-w / 2.0, stickManBoundingRect.bottom() + 25.0); + + QGraphicsScene *scene = new QGraphicsScene(); + scene->addItem(stickMan); + scene->addItem(textItem); + scene->setBackgroundBrush(Qt::black); + + GraphicsView *view = new GraphicsView(); + view->setRenderHints(QPainter::Antialiasing); + view->setTransformationAnchor(QGraphicsView::NoAnchor); + view->setScene(scene); + view->showFullScreen(); + view->setFocus(); + view->setSceneRect(scene->sceneRect()); + + LifeCycle *cycle = new LifeCycle(stickMan, view); + cycle->setDeathAnimation("animations/dead"); + + cycle->addActivity("animations/jumping", Qt::Key_J); + cycle->addActivity("animations/dancing", Qt::Key_D); + cycle->addActivity("animations/chilling", Qt::Key_C); + cycle->start(); + + return app.exec(); +} diff --git a/examples/animation/stickman/node.cpp b/examples/animation/stickman/node.cpp new file mode 100644 index 0000000..9c485d9 --- /dev/null +++ b/examples/animation/stickman/node.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "node.h" +#include "stickman.h" + +#include +#include +#include + +Node::Node(const QPointF &pos, QGraphicsItem *parent) + : QGraphicsItem(parent), m_dragging(false) +{ + setPos(pos); +} + +Node::~Node() +{ +} + +QRectF Node::boundingRect() const +{ + return QRectF(-6.0, -6.0, 12.0, 12.0); +} + +void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + painter->setPen(Qt::white); + painter->drawEllipse(QPointF(0.0, 0.0), 5.0, 5.0); +} + +QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == QGraphicsItem::ItemPositionChange) + emit positionChanged(); + + return QGraphicsItem::itemChange(change, value); +} + +void Node::mousePressEvent(QGraphicsSceneMouseEvent *) +{ + m_dragging = true; +} + +void Node::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if (m_dragging) + setPos(mapToParent(event->pos())); +} + +void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *) +{ + m_dragging = false; +} diff --git a/examples/animation/stickman/node.h b/examples/animation/stickman/node.h new file mode 100644 index 0000000..72eae87 --- /dev/null +++ b/examples/animation/stickman/node.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef NODE_H +#define NODE_H + +#include + +class Node: public QObject, public QGraphicsItem +{ + Q_OBJECT + Q_PROPERTY(QPointF position READ pos WRITE setPos); +public: + Node(const QPointF &pos, QGraphicsItem *parent = 0); + ~Node(); + + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +signals: + void positionChanged(); + +protected: + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + + void mousePressEvent(QGraphicsSceneMouseEvent *); + void mouseMoveEvent(QGraphicsSceneMouseEvent *); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *); + +private: + bool m_dragging; +}; + +#endif diff --git a/examples/animation/stickman/stickman.cpp b/examples/animation/stickman/stickman.cpp new file mode 100644 index 0000000..e00ea41 --- /dev/null +++ b/examples/animation/stickman/stickman.cpp @@ -0,0 +1,339 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "stickman.h" +#include "node.h" + +#include +#include + +#define _USE_MATH_DEFINES +#include + +static const int NodeCount = 16; +static const qreal Coords[NodeCount * 2] = { + 0.0, -150.0, // head, #0 + + 0.0, -100.0, // body pentagon, top->bottom, left->right, #1 - 5 + -50.0, -50.0, + 50.0, -50.0, + -25.0, 50.0, + 25.0, 50.0, + + -100.0, 0.0, // right arm, #6 - 7 + -125.0, 50.0, + + 100.0, 0.0, // left arm, #8 - 9 + 125.0, 50.0, + + -35.0, 75.0, // lower body, #10 - 11 + 35.0, 75.0, + + -25.0, 200.0, // right leg, #12 - 13 + -30.0, 300.0, + + 25.0, 200.0, // left leg, #14 - 15 + 30.0, 300.0 + +}; + +static const int BoneCount = 24; +static const int Bones[BoneCount * 2] = { + 0, 1, // neck + + 1, 2, // body + 1, 3, + 1, 4, + 1, 5, + 2, 3, + 2, 4, + 2, 5, + 3, 4, + 3, 5, + 4, 5, + + 2, 6, // right arm + 6, 7, + + 3, 8, // left arm + 8, 9, + + 4, 10, // lower body + 4, 11, + 5, 10, + 5, 11, + 10, 11, + + 10, 12, // right leg + 12, 13, + + 11, 14, // left leg + 14, 15 + +}; + +StickMan::StickMan() +{ + m_nodes = new Node*[NodeCount]; + m_sticks = true; + m_isDead = false; + m_pixmap = QPixmap("images/head.png"); + m_penColor = Qt::white; + m_fillColor = Qt::black; + + // Set up start position of limbs + for (int i=0; ipos() - node2->pos(); + m_perfectBoneLengths[i] = sqrt(pow(dist.x(),2) + pow(dist.y(),2)); + } + + startTimer(10); +} + +StickMan::~StickMan() +{ + delete m_nodes; +} + +void StickMan::childPositionChanged() +{ + prepareGeometryChange(); +} + +void StickMan::setDrawSticks(bool on) +{ + m_sticks = on; + for (int i=0;isetVisible(on); + } +} + +QRectF StickMan::boundingRect() const +{ + // account for head radius=50.0 plus pen which is 5.0 + return childrenBoundingRect().adjusted(-55.0, -55.0, 55.0, 55.0); +} + +int StickMan::nodeCount() const +{ + return NodeCount; +} + +Node *StickMan::node(int idx) const +{ + if (idx >= 0 && idx < NodeCount) + return m_nodes[idx]; + else + return 0; +} + +void StickMan::timerEvent(QTimerEvent *) +{ + update(); +} + +void StickMan::stabilize() +{ + static const qreal threshold = 0.001; + + for (int i=0; ipos(); + QPointF pos2 = node2->pos(); + + QPointF dist = pos1 - pos2; + qreal length = sqrt(pow(dist.x(),2) + pow(dist.y(),2)); + qreal diff = (length - m_perfectBoneLengths[i]) / length; + + QPointF p = dist * (0.5 * diff); + if (p.x() > threshold && p.y() > threshold) { + pos1 -= p; + pos2 += p; + + node1->setPos(pos1); + node2->setPos(pos2); + } + } +} + +QPointF StickMan::posFor(int idx) const +{ + return m_nodes[idx]->pos(); +} + +//#include +void StickMan::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + /* static int frames = 0; + static QTime time; + if (frames++ % 100 == 0) { + frames = 1; + time.restart(); + } + + if (time.elapsed() > 0) { + painter->setPen(Qt::white); + painter->drawText(0, 0, QString::number(frames / (time.elapsed() / 1000.0))); + }*/ + + stabilize(); + if (m_sticks) { + painter->setPen(Qt::white); + for (int i=0; idrawLine(node1->pos(), node2->pos()); + } + } else { + // first bone is neck and will be used for head + + QPainterPath path; + path.moveTo(posFor(0)); + path.lineTo(posFor(1)); + + // right arm + path.lineTo(posFor(2)); + path.lineTo(posFor(6)); + path.lineTo(posFor(7)); + + // left arm + path.moveTo(posFor(3)); + path.lineTo(posFor(8)); + path.lineTo(posFor(9)); + + // body + path.moveTo(posFor(2)); + path.lineTo(posFor(4)); + path.lineTo(posFor(10)); + path.lineTo(posFor(11)); + path.lineTo(posFor(5)); + path.lineTo(posFor(3)); + path.lineTo(posFor(1)); + + // right leg + path.moveTo(posFor(10)); + path.lineTo(posFor(12)); + path.lineTo(posFor(13)); + + // left leg + path.moveTo(posFor(11)); + path.lineTo(posFor(14)); + path.lineTo(posFor(15)); + + painter->setPen(QPen(m_penColor, 5.0, Qt::SolidLine, Qt::RoundCap)); + painter->drawPath(path); + + { + int n1 = Bones[0]; + int n2 = Bones[1]; + Node *node1 = m_nodes[n1]; + Node *node2 = m_nodes[n2]; + + QPointF dist = node2->pos() - node1->pos(); + + qreal sinAngle = dist.x() / sqrt(pow(dist.x(), 2) + pow(dist.y(), 2)); + qreal angle = asin(sinAngle) * 180.0 / M_PI; + + QPointF headPos = node1->pos(); + painter->translate(headPos); + painter->rotate(-angle); + + painter->setBrush(m_fillColor); + painter->drawEllipse(QPointF(0,0), 50.0, 50.0); + + painter->setBrush(m_penColor); + painter->setPen(QPen(m_penColor, 2.5, Qt::SolidLine, Qt::RoundCap)); + + // eyes + if (m_isDead) { + painter->drawLine(-30.0, -30.0, -20.0, -20.0); + painter->drawLine(-20.0, -30.0, -30.0, -20.0); + + painter->drawLine(20.0, -30.0, 30.0, -20.0); + painter->drawLine(30.0, -30.0, 20.0, -20.0); + } else { + painter->drawChord(QRectF(-30.0, -30.0, 25.0, 70.0), 30.0*16, 120.0*16); + painter->drawChord(QRectF(5.0, -30.0, 25.0, 70.0), 30.0*16, 120.0*16); + } + + // mouth + if (m_isDead) { + painter->drawLine(-28.0, 2.0, 29.0, 2.0); + } else { + painter->setBrush(QColor(128, 0, 64 )); + painter->drawChord(QRectF(-28.0, 2.0-55.0/2.0, 57.0, 55.0), 0.0, -180.0*16); + } + + // pupils + if (!m_isDead) { + painter->setPen(QPen(m_fillColor, 1.0, Qt::SolidLine, Qt::RoundCap)); + painter->setBrush(m_fillColor); + painter->drawEllipse(QPointF(-12.0, -25.0), 5.0, 5.0); + painter->drawEllipse(QPointF(22.0, -25.0), 5.0, 5.0); + } + } + } +} + + + diff --git a/examples/animation/stickman/stickman.h b/examples/animation/stickman/stickman.h new file mode 100644 index 0000000..6395272 --- /dev/null +++ b/examples/animation/stickman/stickman.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef STICKMAN_H +#define STICKMAN_H + +#include + +const int LimbCount = 16; + +class Node; +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE +class StickMan: public QObject, public QGraphicsItem +{ + Q_OBJECT + Q_PROPERTY(QColor penColor WRITE setPenColor READ penColor) + Q_PROPERTY(QColor fillColor WRITE setFillColor READ fillColor) + Q_PROPERTY(bool isDead WRITE setIsDead READ isDead) +public: + StickMan(); + ~StickMan(); + + virtual QRectF boundingRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + int nodeCount() const; + Node *node(int idx) const; + + void setDrawSticks(bool on); + bool drawSticks() const { return m_sticks; } + + QColor penColor() const { return m_penColor; } + void setPenColor(const QColor &color) { m_penColor = color; } + + QColor fillColor() const { return m_fillColor; } + void setFillColor(const QColor &color) { m_fillColor = color; } + + bool isDead() const { return m_isDead; } + void setIsDead(bool isDead) { m_isDead = isDead; } + +public slots: + void stabilize(); + void childPositionChanged(); + +protected: + void timerEvent(QTimerEvent *e); + +private: + QPointF posFor(int idx) const; + + Node **m_nodes; + qreal *m_perfectBoneLengths; + + uint m_sticks : 1; + uint m_isDead : 1; + uint m_reserved : 30; + + QPixmap m_pixmap; + QColor m_penColor; + QColor m_fillColor; +}; + +#endif // STICKMAN_H diff --git a/examples/animation/stickman/stickman.pro b/examples/animation/stickman/stickman.pro new file mode 100644 index 0000000..956b49c --- /dev/null +++ b/examples/animation/stickman/stickman.pro @@ -0,0 +1,19 @@ +HEADERS += stickman.h \ + animation.h \ + node.h \ + lifecycle.h \ + graphicsview.h +SOURCES += main.cpp \ + stickman.cpp \ + animation.cpp \ + node.cpp \ + lifecycle.cpp \ + graphicsview.cpp + +include(editor/editor.pri) + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/stickman +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS stickman.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/stickman +INSTALLS += target sources diff --git a/examples/animation/sub-attaq/animationmanager.cpp b/examples/animation/sub-attaq/animationmanager.cpp new file mode 100644 index 0000000..477d3bd --- /dev/null +++ b/examples/animation/sub-attaq/animationmanager.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//Own +#include "animationmanager.h" + +//Qt +#include +#include + +// the universe's only animation manager +AnimationManager *AnimationManager::instance = 0; + +AnimationManager::AnimationManager() +{ +} + +AnimationManager *AnimationManager::self() +{ + if (!instance) + instance = new AnimationManager; + return instance; +} + +void AnimationManager::registerAnimation(QAbstractAnimation *anim) +{ + animations.append(anim); +} + +void AnimationManager::unregisterAnimation(QAbstractAnimation *anim) +{ + animations.removeAll(anim); +} + +void AnimationManager::unregisterAllAnimations() +{ + animations.clear(); +} + +void AnimationManager::pauseAll() +{ + foreach (QAbstractAnimation* animation, animations) + { + if (animation->state() == QAbstractAnimation::Running) + animation->pause(); + } +} +void AnimationManager::resumeAll() +{ + foreach (QAbstractAnimation* animation, animations) + { + if (animation->state() == QAbstractAnimation::Paused) + animation->resume(); + } +} diff --git a/examples/animation/sub-attaq/animationmanager.h b/examples/animation/sub-attaq/animationmanager.h new file mode 100644 index 0000000..a563c96 --- /dev/null +++ b/examples/animation/sub-attaq/animationmanager.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANIMATIONMANAGER_H +#define ANIMATIONMANAGER_H + +#include + +QT_BEGIN_NAMESPACE +class QAbstractAnimation; +QT_END_NAMESPACE + +class AnimationManager : public QObject +{ +Q_OBJECT +public: + AnimationManager(); + void registerAnimation(QAbstractAnimation *anim); + void unregisterAnimation(QAbstractAnimation *anim); + void unregisterAllAnimations(); + static AnimationManager *self(); + +public slots: + void pauseAll(); + void resumeAll(); + +private: + static AnimationManager *instance; + QList animations; +}; + +#endif // ANIMATIONMANAGER_H diff --git a/examples/animation/sub-attaq/boat.cpp b/examples/animation/sub-attaq/boat.cpp new file mode 100644 index 0000000..63d12bb --- /dev/null +++ b/examples/animation/sub-attaq/boat.cpp @@ -0,0 +1,318 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//Own +#include "boat.h" +#include "boat_p.h" +#include "bomb.h" +#include "pixmapitem.h" +#include "graphicsscene.h" +#include "animationmanager.h" +#include "custompropertyanimation.h" +#include "qanimationstate.h" + +//Qt +#include +#include +#include +#include +#include +#include + +static QAbstractAnimation *setupDestroyAnimation(Boat *boat) +{ + QSequentialAnimationGroup *group = new QSequentialAnimationGroup(boat); +#if QT_VERSION >=0x040500 + PixmapItem *step1 = new PixmapItem(QString("explosion/boat/step1"),GraphicsScene::Big, boat); + step1->setZValue(6); + PixmapItem *step2 = new PixmapItem(QString("explosion/boat/step2"),GraphicsScene::Big, boat); + step2->setZValue(6); + PixmapItem *step3 = new PixmapItem(QString("explosion/boat/step3"),GraphicsScene::Big, boat); + step3->setZValue(6); + PixmapItem *step4 = new PixmapItem(QString("explosion/boat/step4"),GraphicsScene::Big, boat); + step4->setZValue(6); + step1->setOpacity(0); + step2->setOpacity(0); + step3->setOpacity(0); + step4->setOpacity(0); + CustomPropertyAnimation *anim1 = new CustomPropertyAnimation(boat); + anim1->setMemberFunctions((QGraphicsItem*)step1, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim1->setDuration(100); + anim1->setEndValue(1); + CustomPropertyAnimation *anim2 = new CustomPropertyAnimation(boat); + anim2->setMemberFunctions((QGraphicsItem*)step2, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim2->setDuration(100); + anim2->setEndValue(1); + CustomPropertyAnimation *anim3 = new CustomPropertyAnimation(boat); + anim3->setMemberFunctions((QGraphicsItem*)step3, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim3->setDuration(100); + anim3->setEndValue(1); + CustomPropertyAnimation *anim4 = new CustomPropertyAnimation(boat); + anim4->setMemberFunctions((QGraphicsItem*)step4, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim4->setDuration(100); + anim4->setEndValue(1); + CustomPropertyAnimation *anim5 = new CustomPropertyAnimation(boat); + anim5->setMemberFunctions((QGraphicsItem*)step1, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim5->setDuration(100); + anim5->setEndValue(0); + CustomPropertyAnimation *anim6 = new CustomPropertyAnimation(boat); + anim6->setMemberFunctions((QGraphicsItem*)step2, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim6->setDuration(100); + anim6->setEndValue(0); + CustomPropertyAnimation *anim7 = new CustomPropertyAnimation(boat); + anim7->setMemberFunctions((QGraphicsItem*)step3, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim7->setDuration(100); + anim7->setEndValue(0); + CustomPropertyAnimation *anim8 = new CustomPropertyAnimation(boat); + anim8->setMemberFunctions((QGraphicsItem*)step4, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim8->setDuration(100); + anim8->setEndValue(0); + group->addAnimation(anim1); + group->addAnimation(anim2); + group->addAnimation(anim3); + group->addAnimation(anim4); + group->addAnimation(anim5); + group->addAnimation(anim6); + group->addAnimation(anim7); + group->addAnimation(anim8); +#else + // work around for a bug where we don't transition if the duration is zero. + QtPauseAnimation *anim = new QtPauseAnimation(group); + anim->setDuration(1); + group->addAnimation(anim); +#endif + AnimationManager::self()->registerAnimation(group); + return group; +} + + + +Boat::Boat(QGraphicsItem * parent, Qt::WindowFlags wFlags) + : QGraphicsWidget(parent,wFlags), speed(0), bombsAlreadyLaunched(0), direction(Boat::None), movementAnimation(0) +{ + pixmapItem = new PixmapItem(QString("boat"),GraphicsScene::Big, this); + setZValue(4); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable); + resize(pixmapItem->boundingRect().size()); + + //The movement animation used to animate the boat + movementAnimation = new QPropertyAnimation(this, "pos"); + + //The movement animation used to animate the boat + destroyAnimation = setupDestroyAnimation(this); + + //We setup the state machien of the boat + machine = new QStateMachine(this); + QState *moving = new QState(machine->rootState()); + StopState *stopState = new StopState(this, moving); + machine->setInitialState(moving); + moving->setInitialState(stopState); + MoveStateRight *moveStateRight = new MoveStateRight(this, moving); + MoveStateLeft *moveStateLeft = new MoveStateLeft(this, moving); + LaunchStateRight *launchStateRight = new LaunchStateRight(this, machine->rootState()); + LaunchStateLeft *launchStateLeft = new LaunchStateLeft(this, machine->rootState()); + + //then setup the transitions for the rightMove state + KeyStopTransition *leftStopRight = new KeyStopTransition(this, QEvent::KeyPress, Qt::Key_Left); + leftStopRight->setTargetState(stopState); + KeyMoveTransition *leftMoveRight = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Left); + leftMoveRight->setTargetState(moveStateRight); + KeyMoveTransition *rightMoveRight = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right); + rightMoveRight->setTargetState(moveStateRight); + KeyMoveTransition *rightMoveStop = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right); + rightMoveStop->setTargetState(moveStateRight); + + //then setup the transitions for the leftMove state + KeyStopTransition *rightStopLeft = new KeyStopTransition(this, QEvent::KeyPress, Qt::Key_Right); + rightStopLeft->setTargetState(stopState); + KeyMoveTransition *rightMoveLeft = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right); + rightMoveLeft->setTargetState(moveStateLeft); + KeyMoveTransition *leftMoveLeft = new KeyMoveTransition(this, QEvent::KeyPress,Qt::Key_Left); + leftMoveLeft->setTargetState(moveStateLeft); + KeyMoveTransition *leftMoveStop = new KeyMoveTransition(this, QEvent::KeyPress,Qt::Key_Left); + leftMoveStop->setTargetState(moveStateLeft); + + //We set up the right move state + moveStateRight->addTransition(leftStopRight); + moveStateRight->addTransition(leftMoveRight); + moveStateRight->addTransition(rightMoveRight); + stopState->addTransition(rightMoveStop); + + //We set up the left move state + moveStateLeft->addTransition(rightStopLeft); + moveStateLeft->addTransition(leftMoveLeft); + moveStateLeft->addTransition(rightMoveLeft); + stopState->addTransition(leftMoveStop); + + //The animation is finished, it means we reached the border of the screen, the boat is stopped so we move to the stop state + moveStateLeft->addTransition(movementAnimation, SIGNAL(finished()), stopState); + moveStateRight->addTransition(movementAnimation, SIGNAL(finished()), stopState); + + //We set up the keys for dropping bombs + KeyLaunchTransition *upFireLeft = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up); + upFireLeft->setTargetState(launchStateRight); + KeyLaunchTransition *upFireRight = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up); + upFireRight->setTargetState(launchStateRight); + KeyLaunchTransition *upFireStop = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up); + upFireStop->setTargetState(launchStateRight); + KeyLaunchTransition *downFireLeft = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down); + downFireLeft->setTargetState(launchStateLeft); + KeyLaunchTransition *downFireRight = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down); + downFireRight->setTargetState(launchStateLeft); + KeyLaunchTransition *downFireMove = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down); + downFireMove->setTargetState(launchStateLeft); + + //We set up transitions for fire up + moveStateRight->addTransition(upFireRight); + moveStateLeft->addTransition(upFireLeft); + stopState->addTransition(upFireStop); + + //We set up transitions for fire down + moveStateRight->addTransition(downFireRight); + moveStateLeft->addTransition(downFireLeft); + stopState->addTransition(downFireMove); + + //Finally the launch state should come back to its original state + QHistoryState *historyState = new QHistoryState(moving); + launchStateLeft->addTransition(historyState); + launchStateRight->addTransition(historyState); + + QFinalState *final = new QFinalState(machine->rootState()); + + //This state play the destroyed animation + QAnimationState *destroyedState = new QAnimationState(machine->rootState()); + destroyedState->setAnimation(destroyAnimation); + + //Play a nice animation when the boat is destroyed + moving->addTransition(this, SIGNAL(boatDestroyed()),destroyedState); + + //Transition to final state when the destroyed animation is finished + destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final); + + //The machine has finished to be executed, then the boat is dead + connect(machine,SIGNAL(finished()),this, SIGNAL(boatExecutionFinished())); + +} + +void Boat::run() +{ + //We register animations + AnimationManager::self()->registerAnimation(movementAnimation); + AnimationManager::self()->registerAnimation(destroyAnimation); + machine->start(); +} + +void Boat::stop() +{ + movementAnimation->stop(); + machine->stop(); +} + +void Boat::updateBoatMovement() +{ + if (speed == 0 || direction == Boat::None) { + movementAnimation->stop(); + return; + } + + movementAnimation->stop(); + movementAnimation->setStartValue(pos()); + + if (direction == Boat::Left) { + movementAnimation->setEndValue(QPointF(0,y())); + movementAnimation->setDuration(x()/speed*15); + } + else /*if (direction == Boat::Right)*/ { + movementAnimation->setEndValue(QPointF(scene()->width()-size().width(),y())); + movementAnimation->setDuration((scene()->width()-size().width()-x())/speed*15); + } + movementAnimation->start(); +} + +void Boat::destroy() +{ + movementAnimation->stop(); + emit boatDestroyed(); +} + +int Boat::bombsLaunched() const +{ + return bombsAlreadyLaunched; +} + +void Boat::setBombsLaunched(int number) +{ + if (number > MAX_BOMB) { + qWarning("Boat::setBombsLaunched : It impossible to launch that number of bombs"); + return; + } + bombsAlreadyLaunched = number; +} + +int Boat::currentSpeed() const +{ + return speed; +} + +void Boat::setCurrentSpeed(int speed) +{ + if (speed > 3 || speed < 0) { + qWarning("Boat::setCurrentSpeed: The boat can't run on that speed"); + return; + } + this->speed = speed; +} + +enum Boat::Movement Boat::currentDirection() const +{ + return direction; +} + +void Boat::setCurrentDirection(Movement direction) +{ + this->direction = direction; +} + +int Boat::type() const +{ + return Type; +} diff --git a/examples/animation/sub-attaq/boat.h b/examples/animation/sub-attaq/boat.h new file mode 100644 index 0000000..08a9fa2 --- /dev/null +++ b/examples/animation/sub-attaq/boat.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __BOAT__H__ +#define __BOAT__H__ + +//Qt +#include +#include + +#include + +class PixmapItem; +class Bomb; +QT_BEGIN_NAMESPACE +class QVariantAnimation; +class QAbstractAnimation; +class QStateMachine; +QT_END_NAMESPACE + +class Boat : public QGraphicsWidget +{ +Q_OBJECT +Q_PROPERTY(QPointF pos READ pos WRITE setPos) +public: + enum Movement { + None = 0, + Left, + Right + }; + enum { Type = UserType + 2 }; + Boat(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); + void destroy(); + void run(); + void stop(); + + int bombsLaunched() const; + void setBombsLaunched(int number); + + int currentSpeed() const; + void setCurrentSpeed(int speed); + + enum Movement currentDirection() const; + void setCurrentDirection(Movement direction); + + void updateBoatMovement(); + + virtual int type() const; + +Q_SIGNALS: + void boatDestroyed(); + void boatExecutionFinished(); + +private: + int speed; + int bombsAlreadyLaunched; + Movement direction; + QVariantAnimation *movementAnimation; + QAbstractAnimation *destroyAnimation; + QStateMachine *machine; + PixmapItem *pixmapItem; +}; + +#endif //__BOAT__H__ diff --git a/examples/animation/sub-attaq/boat_p.h b/examples/animation/sub-attaq/boat_p.h new file mode 100644 index 0000000..a8a24a6 --- /dev/null +++ b/examples/animation/sub-attaq/boat_p.h @@ -0,0 +1,256 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BOAT_P_H +#define BOAT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +//Own +#include "bomb.h" +#include "graphicsscene.h" + +// Qt +#include + +static const int MAX_BOMB = 5; + + +//These transtion test if we have to stop the boat (i.e current speed is 1) +class KeyStopTransition : public QKeyEventTransition +{ +public: + KeyStopTransition(Boat *boat, QEvent::Type type, int key) + : QKeyEventTransition(boat, type, key) + { + this->boat = boat; + this->key = key; + } +protected: + virtual bool eventTest(QEvent *event) + { + Q_UNUSED(event); + if (!QKeyEventTransition::eventTest(event)) + return false; + if (boat->currentSpeed() == 1) + return true; + else + return false; + } +private: + Boat * boat; + int key; +}; + +//These transtion test if we have to move the boat (i.e current speed was 0 or another value) + class KeyMoveTransition : public QKeyEventTransition +{ +public: + KeyMoveTransition(Boat *boat, QEvent::Type type, int key) + : QKeyEventTransition(boat, type, key) + { + this->boat = boat; + this->key = key; + } +protected: + virtual bool eventTest(QEvent *event) + { + Q_UNUSED(event); + if (!QKeyEventTransition::eventTest(event)) + return false; + if (boat->currentSpeed() >= 0) + return true; + else + return false; + + } + void onTransition(QEvent *) + { + //We decrease the speed if needed + if (key == Qt::Key_Left && boat->currentDirection() == Boat::Right) + boat->setCurrentSpeed(boat->currentSpeed() - 1); + else if (key == Qt::Key_Right && boat->currentDirection() == Boat::Left) + boat->setCurrentSpeed(boat->currentSpeed() - 1); + else if (boat->currentSpeed() < 3) + boat->setCurrentSpeed(boat->currentSpeed() + 1); + boat->updateBoatMovement(); + } +private: + Boat * boat; + int key; +}; + +//This transition trigger the bombs launch + class KeyLaunchTransition : public QKeyEventTransition +{ +public: + KeyLaunchTransition(Boat *boat, QEvent::Type type, int key) + : QKeyEventTransition(boat, type, key) + { + this->boat = boat; + this->key = key; + } +protected: + virtual bool eventTest(QEvent *event) + { + Q_UNUSED(event); + if (!QKeyEventTransition::eventTest(event)) + return false; + //We have enough bomb? + if (boat->bombsLaunched() < MAX_BOMB) + return true; + else + return false; + } +private: + Boat * boat; + int key; +}; + +//This state is describing when the boat is moving right +class MoveStateRight : public QState +{ +public: + MoveStateRight(Boat *boat,QState *parent = 0) : QState(parent) + { + this->boat = boat; + } +protected: + void onEntry(QEvent *) + { + boat->setCurrentDirection(Boat::Right); + boat->updateBoatMovement(); + } +private: + Boat * boat; +}; + + //This state is describing when the boat is moving left +class MoveStateLeft : public QState +{ +public: + MoveStateLeft(Boat *boat,QState *parent = 0) : QState(parent) + { + this->boat = boat; + } +protected: + void onEntry(QEvent *) + { + boat->setCurrentDirection(Boat::Left); + boat->updateBoatMovement(); + } +private: + Boat * boat; +}; + +//This state is describing when the boat is in a stand by position +class StopState : public QState +{ +public: + StopState(Boat *boat,QState *parent = 0) : QState(parent) + { + this->boat = boat; + } +protected: + void onEntry(QEvent *) + { + boat->setCurrentSpeed(0); + boat->setCurrentDirection(Boat::None); + boat->updateBoatMovement(); + } +private: + Boat * boat; +}; + +//This state is describing the launch of the torpedo on the right +class LaunchStateRight : public QState +{ +public: + LaunchStateRight(Boat *boat,QState *parent = 0) : QState(parent) + { + this->boat = boat; + } +protected: + void onEntry(QEvent *) + { + Bomb *b = new Bomb(); + b->setPos(boat->x()+boat->size().width(),boat->y()); + GraphicsScene *scene = static_cast(boat->scene()); + scene->addItem(b); + b->launch(Bomb::Right); + boat->setBombsLaunched(boat->bombsLaunched() + 1); + } +private: + Boat * boat; +}; + +//This state is describing the launch of the torpedo on the left +class LaunchStateLeft : public QState +{ +public: + LaunchStateLeft(Boat *boat,QState *parent = 0) : QState(parent) + { + this->boat = boat; + } +protected: + void onEntry(QEvent *) + { + Bomb *b = new Bomb(); + b->setPos(boat->x() - b->size().width(), boat->y()); + GraphicsScene *scene = static_cast(boat->scene()); + scene->addItem(b); + b->launch(Bomb::Left); + boat->setBombsLaunched(boat->bombsLaunched() + 1); + } +private: + Boat * boat; +}; + +#endif // BOAT_P_H diff --git a/examples/animation/sub-attaq/bomb.cpp b/examples/animation/sub-attaq/bomb.cpp new file mode 100644 index 0000000..f1f5324 --- /dev/null +++ b/examples/animation/sub-attaq/bomb.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//Own +#include "bomb.h" +#include "submarine.h" +#include "pixmapitem.h" +#include "animationmanager.h" +#include "qanimationstate.h" + +//Qt +#include +#include +#include +#include + +Bomb::Bomb(QGraphicsItem * parent, Qt::WindowFlags wFlags) + : QGraphicsWidget(parent,wFlags), launchAnimation(0) +{ + pixmapItem = new PixmapItem(QString("bomb"),GraphicsScene::Big, this); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setFlags(QGraphicsItem::ItemIsMovable); + setZValue(2); + resize(pixmapItem->boundingRect().size()); +} + +void Bomb::launch(Bomb::Direction direction) +{ + launchAnimation = new QSequentialAnimationGroup(); + AnimationManager::self()->registerAnimation(launchAnimation); + qreal delta = direction == Right ? 20 : - 20; + QPropertyAnimation *anim = new QPropertyAnimation(this, "pos"); + anim->setEndValue(QPointF(x() + delta,y() - 20)); + anim->setDuration(150); + launchAnimation->addAnimation(anim); + anim = new QPropertyAnimation(this, "pos"); + anim->setEndValue(QPointF(x() + delta*2, y() )); + anim->setDuration(150); + launchAnimation->addAnimation(anim); + anim = new QPropertyAnimation(this, "pos"); + anim->setEndValue(QPointF(x() + delta*2,scene()->height())); + anim->setDuration(y()/2*60); + launchAnimation->addAnimation(anim); + connect(anim,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationLaunchValueChanged(const QVariant &))); + + //We setup the state machine of the bomb + QStateMachine *machine = new QStateMachine(this); + + //This state is when the launch animation is playing + QAnimationState *launched = new QAnimationState(machine->rootState()); + launched->setAnimation(launchAnimation); + + //End + QFinalState *final = new QFinalState(machine->rootState()); + + machine->setInitialState(launched); + + //### Add a nice animation when the bomb is destroyed + launched->addTransition(this, SIGNAL(bombExplosed()),final); + + //If the animation is finished, then we move to the final state + launched->addTransition(launched, SIGNAL(animationFinished()), final); + + //The machine has finished to be executed, then the boat is dead + connect(machine,SIGNAL(finished()),this, SIGNAL(bombExecutionFinished())); + + machine->start(); + +} + +void Bomb::onAnimationLaunchValueChanged(const QVariant &) +{ + foreach (QGraphicsItem * item , collidingItems(Qt::IntersectsItemBoundingRect)) { + if (item->type() == SubMarine::Type) { + SubMarine *s = static_cast(item); + destroy(); + s->destroy(); + } + } +} + +void Bomb::destroy() +{ + launchAnimation->stop(); + emit bombExplosed(); +} diff --git a/examples/animation/sub-attaq/bomb.h b/examples/animation/sub-attaq/bomb.h new file mode 100644 index 0000000..226d056 --- /dev/null +++ b/examples/animation/sub-attaq/bomb.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __BOMB__H__ +#define __BOMB__H__ + +//Qt +#include +#include + +class PixmapItem; + +class Bomb : public QGraphicsWidget +{ +Q_OBJECT +Q_PROPERTY(QPointF pos READ pos WRITE setPos) +public: + enum Direction { + Left = 0, + Right + }; + Bomb(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); + void launch(Direction direction); + void destroy(); + +Q_SIGNALS: + void bombExplosed(); + void bombExecutionFinished(); + +private slots: + void onAnimationLaunchValueChanged(const QVariant &); + +private: + QAnimationGroup *launchAnimation; + PixmapItem *pixmapItem; +}; + +#endif //__BOMB__H__ diff --git a/examples/animation/sub-attaq/custompropertyanimation.cpp b/examples/animation/sub-attaq/custompropertyanimation.cpp new file mode 100644 index 0000000..8226cca --- /dev/null +++ b/examples/animation/sub-attaq/custompropertyanimation.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "custompropertyanimation.h" + +// Qt +#include + +CustomPropertyAnimation::CustomPropertyAnimation(QObject *parent) : + QVariantAnimation(parent), animProp(0) +{ +} + +CustomPropertyAnimation::~CustomPropertyAnimation() +{ +} + +void CustomPropertyAnimation::setProperty(AbstractProperty *_animProp) +{ + if (animProp == _animProp) + return; + delete animProp; + animProp = _animProp; +} + +/*! + \reimp + */ +void CustomPropertyAnimation::updateCurrentValue(const QVariant &value) +{ + if (!animProp || state() == QAbstractAnimation::Stopped) + return; + + animProp->write(value); +} + + +/*! + \reimp +*/ +void CustomPropertyAnimation::updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState) +{ + // Initialize start value + if (oldState == QAbstractAnimation::Stopped) { + if (!animProp) + return; + QVariant def = animProp->read(); + if (def.isValid()) { + const int t = def.userType(); + KeyValues values = keyValues(); + //this ensures that all the keyValues are of type t + for (int i = 0; i < values.count(); ++i) { + QVariantAnimation::KeyValue &pair = values[i]; + if (pair.second.userType() != t) + pair.second.convert(static_cast(t)); + } + //let's now update the key values + setKeyValues(values); + } + + if (animProp && !startValue().isValid() && currentTime() == 0 + || (currentTime() == duration() && currentLoop() == (loopCount() - 1))) { + setStartValue(def); + } + } + + QVariantAnimation::updateState(oldState, newState); +} + +#include "moc_custompropertyanimation.cpp" diff --git a/examples/animation/sub-attaq/custompropertyanimation.h b/examples/animation/sub-attaq/custompropertyanimation.h new file mode 100644 index 0000000..8654aeb --- /dev/null +++ b/examples/animation/sub-attaq/custompropertyanimation.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUSTOMPROPERTYANIMATION_H +#define CUSTOMPROPERTYANIMATION_H + +#include + +QT_BEGIN_NAMESPACE +class QGraphicsItem; +QT_END_NAMESPACE + +struct AbstractProperty +{ + virtual QVariant read() const = 0; + virtual void write(const QVariant &value) = 0; +}; + + +class CustomPropertyAnimation : public QVariantAnimation +{ + Q_OBJECT + + template + class MemberFunctionProperty : public AbstractProperty + { + public: + typedef T (Target::*Getter)(void) const; + typedef void (Target::*Setter)(T2); + + MemberFunctionProperty(Target* target, Getter getter, Setter setter) + : m_target(target), m_getter(getter), m_setter(setter) {} + + virtual void write(const QVariant &value) + { + if (m_setter) (m_target->*m_setter)(qVariantValue(value)); + } + + virtual QVariant read() const + { + if (m_getter) return qVariantFromValue((m_target->*m_getter)()); + return QVariant(); + } + + private: + Target *m_target; + Getter m_getter; + Setter m_setter; + }; + +public: + CustomPropertyAnimation(QObject *parent = 0); + ~CustomPropertyAnimation(); + + template + void setMemberFunctions(Target* target, T (Target::*getter)() const, void (Target::*setter)(const T& )) + { + setProperty(new MemberFunctionProperty(target, getter, setter)); + } + + template + void setMemberFunctions(Target* target, T (Target::*getter)() const, void (Target::*setter)(T)) + { + setProperty(new MemberFunctionProperty(target, getter, setter)); + } + + void updateCurrentValue(const QVariant &value); + void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); + void setProperty(AbstractProperty *animProp); + +private: + Q_DISABLE_COPY(CustomPropertyAnimation); + AbstractProperty *animProp; +}; + +#endif // CUSTOMPROPERTYANIMATION_H diff --git a/examples/animation/sub-attaq/data.xml b/examples/animation/sub-attaq/data.xml new file mode 100644 index 0000000..41d4754 --- /dev/null +++ b/examples/animation/sub-attaq/data.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/graphicsscene.cpp b/examples/animation/sub-attaq/graphicsscene.cpp new file mode 100644 index 0000000..f2d41bc --- /dev/null +++ b/examples/animation/sub-attaq/graphicsscene.cpp @@ -0,0 +1,374 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//Own +#include "graphicsscene.h" +#include "states.h" +#include "boat.h" +#include "submarine.h" +#include "torpedo.h" +#include "bomb.h" +#include "pixmapitem.h" +#include "custompropertyanimation.h" +#include "animationmanager.h" +#include "qanimationstate.h" +#include "progressitem.h" + +//Qt +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//helper function that creates an animation for position and inserts it into group +static CustomPropertyAnimation *addGraphicsItemPosAnimation(QSequentialAnimationGroup *group, + QGraphicsItem *item, const QPointF &endPos) +{ + CustomPropertyAnimation *ret = new CustomPropertyAnimation(group); + ret->setMemberFunctions(item, &QGraphicsItem::pos, &QGraphicsItem::setPos); + ret->setEndValue(endPos); + ret->setDuration(200); + ret->setEasingCurve(QEasingCurve::OutElastic); + group->addPause(50); + return ret; +} + +//helper function that creates an animation for opacity and inserts it into group +static void addGraphicsItemFadeoutAnimation(QAnimationGroup *group, QGraphicsItem *item) +{ +#if QT_VERSION >=0x040500 + CustomPropertyAnimation *anim = new CustomPropertyAnimation(group); + anim->setMemberFunctions(item, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim->setDuration(800); + anim->setEndValue(0); + anim->setEasingCurve(QEasingCurve::OutQuad); +#else + // work around for a bug where we don't transition if the duration is zero. + QtPauseAnimation *anim = new QtPauseAnimation(group); + anim->setDuration(1); +#endif +} + +GraphicsScene::GraphicsScene(int x, int y, int width, int height, Mode mode) + : QGraphicsScene(x,y,width,height), mode(mode), newAction(0), quitAction(0), boat(0) +{ + backgroundItem = new PixmapItem(QString("background"),mode); + backgroundItem->setZValue(1); + backgroundItem->setPos(0,0); + addItem(backgroundItem); + + PixmapItem *surfaceItem = new PixmapItem(QString("surface"),mode); + surfaceItem->setZValue(3); + surfaceItem->setPos(0,sealLevel() - surfaceItem->boundingRect().height()/2); + addItem(surfaceItem); + + //The item that display score and level + progressItem = new ProgressItem(backgroundItem); + + //We create the boat + boat = new Boat(); + addItem(boat); + boat->setPos(this->width()/2, sealLevel() - boat->size().height()); + boat->hide(); + + //parse the xml that contain all data of the game + QXmlStreamReader reader; + QFile file(QDir::currentPath() + "/data.xml"); + file.open(QIODevice::ReadOnly); + reader.setDevice(&file); + LevelDescription currentLevel; + while (!reader.atEnd()) { + reader.readNext(); + if (reader.tokenType() == QXmlStreamReader::StartElement) { + if (reader.name() == "submarine") + { + SubmarineDescription desc; + desc.name = reader.attributes().value("name").toString(); + desc.points = reader.attributes().value("points").toString().toInt(); + desc.type = reader.attributes().value("type").toString().toInt(); + submarinesData.append(desc); + } + if (reader.name() == "level") + { + currentLevel.id = reader.attributes().value("id").toString().toInt(); + currentLevel.name = reader.attributes().value("name").toString(); + } + if (reader.name() == "subinstance") + { + currentLevel.submarines.append(qMakePair(reader.attributes().value("type").toString().toInt(),reader.attributes().value("nb").toString().toInt())); + } + } + if (reader.tokenType() == QXmlStreamReader::EndElement) { + if (reader.name() == "level") + { + levelsData.insert(currentLevel.id,currentLevel); + currentLevel.submarines.clear(); + } + } + } +} + +qreal GraphicsScene::sealLevel() const +{ + if (mode == Big) + return 220; + else + return 160; +} + +void GraphicsScene::setupScene(const QList &actions) +{ + newAction = actions.at(0); + quitAction = actions.at(1); + + QGraphicsItem *logo_s = addWelcomeItem(QPixmap(":/logo-s")); + QGraphicsItem *logo_u = addWelcomeItem(QPixmap(":/logo-u")); + QGraphicsItem *logo_b = addWelcomeItem(QPixmap(":/logo-b")); + QGraphicsItem *logo_dash = addWelcomeItem(QPixmap(":/logo-dash")); + QGraphicsItem *logo_a = addWelcomeItem(QPixmap(":/logo-a")); + QGraphicsItem *logo_t = addWelcomeItem(QPixmap(":/logo-t")); + QGraphicsItem *logo_t2 = addWelcomeItem(QPixmap(":/logo-t2")); + QGraphicsItem *logo_a2 = addWelcomeItem(QPixmap(":/logo-a2")); + QGraphicsItem *logo_q = addWelcomeItem(QPixmap(":/logo-q")); + QGraphicsItem *logo_excl = addWelcomeItem(QPixmap(":/logo-excl")); + logo_s->setZValue(3); + logo_u->setZValue(4); + logo_b->setZValue(5); + logo_dash->setZValue(6); + logo_a->setZValue(7); + logo_t->setZValue(8); + logo_t2->setZValue(9); + logo_a2->setZValue(10); + logo_q->setZValue(11); + logo_excl->setZValue(12); + logo_s->setPos(QPointF(-1000, -1000)); + logo_u->setPos(QPointF(-800, -1000)); + logo_b->setPos(QPointF(-600, -1000)); + logo_dash->setPos(QPointF(-400, -1000)); + logo_a->setPos(QPointF(1000, 2000)); + logo_t->setPos(QPointF(800, 2000)); + logo_t2->setPos(QPointF(600, 2000)); + logo_a2->setPos(QPointF(400, 2000)); + logo_q->setPos(QPointF(200, 2000)); + logo_excl->setPos(QPointF(0, 2000)); + + QSequentialAnimationGroup * lettersGroupMoving = new QSequentialAnimationGroup(this); + QParallelAnimationGroup * lettersGroupFading = new QParallelAnimationGroup(this); + + //creation of the animations for moving letters + addGraphicsItemPosAnimation(lettersGroupMoving, logo_s, QPointF(300, 150)); + addGraphicsItemPosAnimation(lettersGroupMoving, logo_u, QPointF(350, 150)); + addGraphicsItemPosAnimation(lettersGroupMoving, logo_b, QPointF(400, 120)); + addGraphicsItemPosAnimation(lettersGroupMoving, logo_dash, QPointF(460, 150)); + addGraphicsItemPosAnimation(lettersGroupMoving, logo_a, QPointF(350, 250)); + addGraphicsItemPosAnimation(lettersGroupMoving, logo_t, QPointF(400, 250)); + addGraphicsItemPosAnimation(lettersGroupMoving, logo_t2, QPointF(430, 250)); + addGraphicsItemPosAnimation(lettersGroupMoving, logo_a2, QPointF(465, 250)); + addGraphicsItemPosAnimation(lettersGroupMoving, logo_q, QPointF(510, 250)); + addGraphicsItemPosAnimation(lettersGroupMoving, logo_excl, QPointF(570, 220)); + + //creation of the animations for fading out the letters + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_s); + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_u); + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_b); + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_dash); + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_a); + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_t); + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_t2); + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_a2); + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_q); + addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_excl); + connect(lettersGroupFading, SIGNAL(finished()), this, SLOT(onIntroAnimationFinished())); + + QStateMachine *machine = new QStateMachine(this); + + //This state is when the player is playing + PlayState *gameState = new PlayState(this,machine->rootState()); + + //Final state + QFinalState *final = new QFinalState(machine->rootState()); + + //Animation when the player enter in the game + QAnimationState *lettersMovingState = new QAnimationState(machine->rootState()); + lettersMovingState->setAnimation(lettersGroupMoving); + + //Animation when the welcome screen disappear + QAnimationState *lettersFadingState = new QAnimationState(machine->rootState()); + lettersFadingState->setAnimation(lettersGroupFading); + + //if new game then we fade out the welcome screen and start playing + lettersMovingState->addTransition(newAction, SIGNAL(triggered()),lettersFadingState); + lettersFadingState->addTransition(lettersFadingState, SIGNAL(animationFinished()),gameState); + + //New Game is triggered then player start playing + gameState->addTransition(newAction, SIGNAL(triggered()),gameState); + + //Wanna quit, then connect to CTRL+Q + gameState->addTransition(quitAction, SIGNAL(triggered()),final); + lettersMovingState->addTransition(quitAction, SIGNAL(triggered()),final); + + //Welcome screen is the initial state + machine->setInitialState(lettersMovingState); + + machine->start(); + + //We reach the final state, then we quit + connect(machine,SIGNAL(finished()),this, SLOT(onQuitGameTriggered())); +} + +void GraphicsScene::addItem(Bomb *bomb) +{ + bombs.insert(bomb); + connect(bomb,SIGNAL(bombExecutionFinished()),this, SLOT(onBombExecutionFinished())); + QGraphicsScene::addItem(bomb); +} + +void GraphicsScene::addItem(Torpedo *torpedo) +{ + torpedos.insert(torpedo); + connect(torpedo,SIGNAL(torpedoExecutionFinished()),this, SLOT(onTorpedoExecutionFinished())); + QGraphicsScene::addItem(torpedo); +} + +void GraphicsScene::addItem(SubMarine *submarine) +{ + submarines.insert(submarine); + connect(submarine,SIGNAL(subMarineExecutionFinished()),this, SLOT(onSubMarineExecutionFinished())); + QGraphicsScene::addItem(submarine); +} + +void GraphicsScene::addItem(QGraphicsItem *item) +{ + QGraphicsScene::addItem(item); +} + +void GraphicsScene::mousePressEvent (QGraphicsSceneMouseEvent * event) +{ + event->ignore(); +} + +void GraphicsScene::onQuitGameTriggered() +{ + qApp->closeAllWindows(); +} + +void GraphicsScene::onBombExecutionFinished() +{ + Bomb *bomb = qobject_cast(sender()); + bombs.remove(bomb); + bomb->deleteLater(); + if (boat) + boat->setBombsLaunched(boat->bombsLaunched() - 1); +} + +void GraphicsScene::onTorpedoExecutionFinished() +{ + Torpedo *torpedo = qobject_cast(sender()); + torpedos.remove(torpedo); + torpedo->deleteLater(); +} + +void GraphicsScene::onSubMarineExecutionFinished() +{ + SubMarine *submarine = qobject_cast(sender()); + submarines.remove(submarine); + if (submarines.count() == 0) { + emit allSubMarineDestroyed(submarine->points()); + } else { + emit subMarineDestroyed(submarine->points()); + } + submarine->deleteLater(); +} + +int GraphicsScene::remainingSubMarines() const +{ + return submarines.count(); +} + +void GraphicsScene::clearScene() +{ + foreach (SubMarine *sub,submarines) { + sub->destroy(); + sub->deleteLater(); + } + + foreach (Torpedo *torpedo,torpedos) { + torpedo->destroy(); + torpedo->deleteLater(); + } + + foreach (Bomb *bomb,bombs) { + bomb->destroy(); + bomb->deleteLater(); + } + + submarines.clear(); + bombs.clear(); + torpedos.clear(); + + AnimationManager::self()->unregisterAllAnimations(); + + boat->stop(); + boat->hide(); +} + +QGraphicsPixmapItem *GraphicsScene::addWelcomeItem(const QPixmap &pm) +{ + QGraphicsPixmapItem *item = addPixmap(pm); + welcomeItems << item; + return item; +} + +void GraphicsScene::onIntroAnimationFinished() +{ + qDeleteAll(welcomeItems); + welcomeItems.clear(); +} + diff --git a/examples/animation/sub-attaq/graphicsscene.h b/examples/animation/sub-attaq/graphicsscene.h new file mode 100644 index 0000000..8b0ea96 --- /dev/null +++ b/examples/animation/sub-attaq/graphicsscene.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __GRAPHICSSCENE__H__ +#define __GRAPHICSSCENE__H__ + +//Qt +#include +#include +#include + + +class Boat; +class SubMarine; +class Torpedo; +class Bomb; +class PixmapItem; +class ProgressItem; +QT_BEGIN_NAMESPACE +class QAction; +QT_END_NAMESPACE + +class GraphicsScene : public QGraphicsScene +{ +Q_OBJECT +public: + enum Mode { + Big = 0, + Small + }; + + struct SubmarineDescription { + int type; + int points; + QString name; + }; + + struct LevelDescription { + int id; + QString name; + QList > submarines; + }; + + GraphicsScene(int x, int y, int width, int height, Mode mode = Big); + qreal sealLevel() const; + void setupScene(const QList &actions); + void addItem(Bomb *bomb); + void addItem(Torpedo *torpedo); + void addItem(SubMarine *submarine); + void addItem(QGraphicsItem *item); + int remainingSubMarines() const; + void clearScene(); + QGraphicsPixmapItem *addWelcomeItem(const QPixmap &pm); + +Q_SIGNALS: + void subMarineDestroyed(int); + void allSubMarineDestroyed(int); + +protected: + void mousePressEvent (QGraphicsSceneMouseEvent * event); + +private slots: + void onQuitGameTriggered(); + void onBombExecutionFinished(); + void onTorpedoExecutionFinished(); + void onSubMarineExecutionFinished(); + void onIntroAnimationFinished(); + +private: + Mode mode; + PixmapItem *backgroundItem; + ProgressItem *progressItem; + QAction * newAction; + QAction * quitAction; + Boat *boat; + QSet submarines; + QSet bombs; + QSet torpedos; + QVector welcomeItems; + QVector submarinesData; + QHash levelsData; + + friend class PauseState; + friend class PlayState; + friend class LevelState; + friend class LostState; + friend class WinState; + friend class WinTransition; + friend class UpdateScoreTransition; +}; + +#endif //__GRAPHICSSCENE__H__ + diff --git a/examples/animation/sub-attaq/main.cpp b/examples/animation/sub-attaq/main.cpp new file mode 100644 index 0000000..ffaa86f --- /dev/null +++ b/examples/animation/sub-attaq/main.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + Q_INIT_RESOURCE(subattaq); + + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + + MainWindow w; + w.show(); + + return app.exec(); +} diff --git a/examples/animation/sub-attaq/mainwindow.cpp b/examples/animation/sub-attaq/mainwindow.cpp new file mode 100644 index 0000000..a166241 --- /dev/null +++ b/examples/animation/sub-attaq/mainwindow.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//Own +#include "mainwindow.h" +#include "graphicsscene.h" + +#ifndef QT_NO_OPENGL + #include +#endif +//Qt +#include + +MainWindow::MainWindow() : QMainWindow(0) +{ + QMenuBar *menuBar = new QMenuBar; + QMenu *file = new QMenu(tr("&File"),menuBar); + + QAction *newAction = new QAction(tr("New Game"),file); + newAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N)); + file->addAction(newAction); + QAction *quitAction = new QAction(tr("Quit"),file); + quitAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q)); + file->addAction(quitAction); + + menuBar->addMenu(file); + setMenuBar(menuBar); + + QStringList list = QApplication::arguments(); + if (list.contains("-fullscreen")) { + scene = new GraphicsScene(0, 0, 750, 400,GraphicsScene::Small); + setWindowState(Qt::WindowFullScreen); + } else { + scene = new GraphicsScene(0, 0, 880, 630); + layout()->setSizeConstraint(QLayout::SetFixedSize); + } + + view = new QGraphicsView(scene,this); + view->setAlignment(Qt::AlignLeft | Qt::AlignTop); + QList actions; + actions << newAction << quitAction; + scene->setupScene(actions); +#ifndef QT_NO_OPENGL + view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); +#endif + + setCentralWidget(view); + +} + +MainWindow::~MainWindow() +{ +} + diff --git a/examples/animation/sub-attaq/mainwindow.h b/examples/animation/sub-attaq/mainwindow.h new file mode 100644 index 0000000..87f194a --- /dev/null +++ b/examples/animation/sub-attaq/mainwindow.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __MAINWINDOW__H__ +#define __MAINWINDOW__H__ + +//Qt +#include +class GraphicsScene; +QT_BEGIN_NAMESPACE +class QGraphicsView; +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ +Q_OBJECT +public: + MainWindow(); + ~MainWindow(); + +private: + GraphicsScene *scene; + QGraphicsView *view; +}; + +#endif //__MAINWINDOW__H__ diff --git a/examples/animation/sub-attaq/pics/big/background.png b/examples/animation/sub-attaq/pics/big/background.png new file mode 100644 index 0000000..9f58157 Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/background.png differ diff --git a/examples/animation/sub-attaq/pics/big/boat.png b/examples/animation/sub-attaq/pics/big/boat.png new file mode 100644 index 0000000..be82dff Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/boat.png differ diff --git a/examples/animation/sub-attaq/pics/big/bomb.png b/examples/animation/sub-attaq/pics/big/bomb.png new file mode 100644 index 0000000..3af5f2f Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/bomb.png differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png new file mode 100644 index 0000000..c9fd8b0 Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png new file mode 100644 index 0000000..7528f2d Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png new file mode 100644 index 0000000..aae9c9c Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png new file mode 100644 index 0000000..d697c1b Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png new file mode 100644 index 0000000..88ca514 Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png new file mode 100644 index 0000000..524f589 Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png new file mode 100644 index 0000000..2cca1e8 Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png new file mode 100644 index 0000000..82100a8 Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png differ diff --git a/examples/animation/sub-attaq/pics/big/submarine.png b/examples/animation/sub-attaq/pics/big/submarine.png new file mode 100644 index 0000000..df435dc Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/submarine.png differ diff --git a/examples/animation/sub-attaq/pics/big/surface.png b/examples/animation/sub-attaq/pics/big/surface.png new file mode 100644 index 0000000..4eba29e Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/surface.png differ diff --git a/examples/animation/sub-attaq/pics/big/torpedo.png b/examples/animation/sub-attaq/pics/big/torpedo.png new file mode 100644 index 0000000..f9c2687 Binary files /dev/null and b/examples/animation/sub-attaq/pics/big/torpedo.png differ diff --git a/examples/animation/sub-attaq/pics/scalable/background-n810.svg b/examples/animation/sub-attaq/pics/scalable/background-n810.svg new file mode 100644 index 0000000..ece9f7a --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/background-n810.svg @@ -0,0 +1,171 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/background.svg b/examples/animation/sub-attaq/pics/scalable/background.svg new file mode 100644 index 0000000..0be2680 --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/background.svg @@ -0,0 +1,171 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/boat.svg b/examples/animation/sub-attaq/pics/scalable/boat.svg new file mode 100644 index 0000000..5298821b --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/boat.svg @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/bomb.svg b/examples/animation/sub-attaq/pics/scalable/bomb.svg new file mode 100644 index 0000000..294771a --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/bomb.svg @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/sand.svg b/examples/animation/sub-attaq/pics/scalable/sand.svg new file mode 100644 index 0000000..8af11b7 --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/sand.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/see.svg b/examples/animation/sub-attaq/pics/scalable/see.svg new file mode 100644 index 0000000..0666691 --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/see.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/sky.svg b/examples/animation/sub-attaq/pics/scalable/sky.svg new file mode 100644 index 0000000..1546c08 --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/sky.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg b/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg new file mode 100644 index 0000000..b075179 --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg @@ -0,0 +1,1473 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/submarine.svg b/examples/animation/sub-attaq/pics/scalable/submarine.svg new file mode 100644 index 0000000..8a0ffdd --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/submarine.svg @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/surface.svg b/examples/animation/sub-attaq/pics/scalable/surface.svg new file mode 100644 index 0000000..40ed239 --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/surface.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/scalable/torpedo.svg b/examples/animation/sub-attaq/pics/scalable/torpedo.svg new file mode 100644 index 0000000..48e429d --- /dev/null +++ b/examples/animation/sub-attaq/pics/scalable/torpedo.svg @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/animation/sub-attaq/pics/small/background.png b/examples/animation/sub-attaq/pics/small/background.png new file mode 100644 index 0000000..5ad3db6 Binary files /dev/null and b/examples/animation/sub-attaq/pics/small/background.png differ diff --git a/examples/animation/sub-attaq/pics/small/boat.png b/examples/animation/sub-attaq/pics/small/boat.png new file mode 100644 index 0000000..114ccc3 Binary files /dev/null and b/examples/animation/sub-attaq/pics/small/boat.png differ diff --git a/examples/animation/sub-attaq/pics/small/bomb.png b/examples/animation/sub-attaq/pics/small/bomb.png new file mode 100644 index 0000000..3af5f2f Binary files /dev/null and b/examples/animation/sub-attaq/pics/small/bomb.png differ diff --git a/examples/animation/sub-attaq/pics/small/submarine.png b/examples/animation/sub-attaq/pics/small/submarine.png new file mode 100644 index 0000000..0c0c350 Binary files /dev/null and b/examples/animation/sub-attaq/pics/small/submarine.png differ diff --git a/examples/animation/sub-attaq/pics/small/surface.png b/examples/animation/sub-attaq/pics/small/surface.png new file mode 100644 index 0000000..06d0e47 Binary files /dev/null and b/examples/animation/sub-attaq/pics/small/surface.png differ diff --git a/examples/animation/sub-attaq/pics/small/torpedo.png b/examples/animation/sub-attaq/pics/small/torpedo.png new file mode 100644 index 0000000..f9c2687 Binary files /dev/null and b/examples/animation/sub-attaq/pics/small/torpedo.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-a.png b/examples/animation/sub-attaq/pics/welcome/logo-a.png new file mode 100644 index 0000000..67dd76d Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-a.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-a2.png b/examples/animation/sub-attaq/pics/welcome/logo-a2.png new file mode 100644 index 0000000..17668b0 Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-a2.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-b.png b/examples/animation/sub-attaq/pics/welcome/logo-b.png new file mode 100644 index 0000000..cf6c045 Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-b.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-dash.png b/examples/animation/sub-attaq/pics/welcome/logo-dash.png new file mode 100644 index 0000000..219233c Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-dash.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-excl.png b/examples/animation/sub-attaq/pics/welcome/logo-excl.png new file mode 100644 index 0000000..8dd0a2e Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-excl.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-q.png b/examples/animation/sub-attaq/pics/welcome/logo-q.png new file mode 100644 index 0000000..86e588d Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-q.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-s.png b/examples/animation/sub-attaq/pics/welcome/logo-s.png new file mode 100644 index 0000000..7b6a36e Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-s.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-t.png b/examples/animation/sub-attaq/pics/welcome/logo-t.png new file mode 100644 index 0000000..b2e3526 Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-t.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-t2.png b/examples/animation/sub-attaq/pics/welcome/logo-t2.png new file mode 100644 index 0000000..b11a778 Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-t2.png differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-u.png b/examples/animation/sub-attaq/pics/welcome/logo-u.png new file mode 100644 index 0000000..24eede8 Binary files /dev/null and b/examples/animation/sub-attaq/pics/welcome/logo-u.png differ diff --git a/examples/animation/sub-attaq/pixmapitem.cpp b/examples/animation/sub-attaq/pixmapitem.cpp new file mode 100644 index 0000000..22a363f --- /dev/null +++ b/examples/animation/sub-attaq/pixmapitem.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//Own +#include "pixmapitem.h" + +//Qt +#include + +PixmapItem::PixmapItem(const QString &fileName,GraphicsScene::Mode mode, QGraphicsItem * parent) : QGraphicsPixmapItem(parent),name(fileName) +{ + loadPixmap(mode); +} + +void PixmapItem::loadPixmap(GraphicsScene::Mode mode) +{ + if (mode == GraphicsScene::Big) + setPixmap(":/big/" + name); + else + setPixmap(":/small/" + name); +} diff --git a/examples/animation/sub-attaq/pixmapitem.h b/examples/animation/sub-attaq/pixmapitem.h new file mode 100644 index 0000000..31022c1 --- /dev/null +++ b/examples/animation/sub-attaq/pixmapitem.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __PIXMAPITEM__H__ +#define __PIXMAPITEM__H__ + +//Own +#include "graphicsscene.h" + +//Qt +#include + +class PixmapItem : public QGraphicsPixmapItem +{ +public: + PixmapItem(const QString &fileName, GraphicsScene::Mode mode, QGraphicsItem * parent = 0); + +private: + void loadPixmap(GraphicsScene::Mode mode); + + QString name; + QPixmap pixmap; +}; + +#endif //__PIXMAPITEM__H__ diff --git a/examples/animation/sub-attaq/progressitem.cpp b/examples/animation/sub-attaq/progressitem.cpp new file mode 100644 index 0000000..59ccb9a --- /dev/null +++ b/examples/animation/sub-attaq/progressitem.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "progressitem.h" +#include "pixmapitem.h" + +ProgressItem::ProgressItem (QGraphicsItem * parent) + : QGraphicsTextItem(parent), currentLevel(1), currentScore(0) +{ + setFont(QFont("Comic Sans MS")); + setPos(parentItem()->boundingRect().topRight() - QPointF(180, -5)); +} + +void ProgressItem::setLevel(int level) +{ + currentLevel = level; + updateProgress(); +} + +void ProgressItem::setScore(int score) +{ + currentScore = score; + updateProgress(); +} + +void ProgressItem::updateProgress() +{ + setHtml(QString("Level : %1 Score : %2").arg(currentLevel).arg(currentScore)); +} diff --git a/examples/animation/sub-attaq/progressitem.h b/examples/animation/sub-attaq/progressitem.h new file mode 100644 index 0000000..7b8db4d --- /dev/null +++ b/examples/animation/sub-attaq/progressitem.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PROGRESSITEM_H +#define PROGRESSITEM_H + +//Qt +#include + +class ProgressItem : public QGraphicsTextItem +{ +public: + ProgressItem(QGraphicsItem * parent = 0); + void setLevel(int level); + void setScore(int score); + +private: + void updateProgress(); + int currentLevel; + int currentScore; +}; + +#endif // PROGRESSITEM_H diff --git a/examples/animation/sub-attaq/qanimationstate.cpp b/examples/animation/sub-attaq/qanimationstate.cpp new file mode 100644 index 0000000..26e0ef3 --- /dev/null +++ b/examples/animation/sub-attaq/qanimationstate.cpp @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanimationstate.h" + +#include +#include + + +QT_BEGIN_NAMESPACE + +/*! +\class QAnimationState + +\brief The QAnimationState class provides state that handle an animation and emit +a signal when this animation is finished. + +\ingroup statemachine + +QAnimationState provides a state that handle an animation. It will start this animation +when the state is entered and stop it when it is leaved. When the animation has finished the +state emit animationFinished signal. +QAnimationState is part of \l{The State Machine Framework}. + +\code +QStateMachine machine; +QAnimationState *s = new QAnimationState(machine->rootState()); +QPropertyAnimation *animation = new QPropertyAnimation(obj, "pos"); +s->setAnimation(animation); +QState *s2 = new QState(machine->rootState()); +s->addTransition(s, SIGNAL(animationFinished()), s2); +machine.start(); +\endcode + +\sa QState, {The Animation Framework} +*/ + + +#ifndef QT_NO_ANIMATION + +class QAnimationStatePrivate : public QStatePrivate +{ + Q_DECLARE_PUBLIC(QAnimationState) +public: + QAnimationStatePrivate() + : animation(0) + { + + } + ~QAnimationStatePrivate() {} + + QAbstractAnimation *animation; +}; + +/*! + Constructs a new state with the given \a parent state. +*/ +QAnimationState::QAnimationState(QState *parent) + : QState(*new QAnimationStatePrivate, parent) +{ +} + +/*! + Destroys the animation state. +*/ +QAnimationState::~QAnimationState() +{ +} + +/*! + Set an \a animation for this QAnimationState. If an animation was previously handle by this + state then it won't emit animationFinished for the old animation. The QAnimationState doesn't + take the ownership of the animation. +*/ +void QAnimationState::setAnimation(QAbstractAnimation *animation) +{ + Q_D(QAnimationState); + + if (animation == d->animation) + return; + + //Disconnect from the previous animation if exist + if(d->animation) + disconnect(d->animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); + + d->animation = animation; + + if (d->animation) { + //connect the new animation + connect(d->animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); + } +} + +/*! + Returns the animation handle by this animation state, or 0 if there is no animation. +*/ +QAbstractAnimation* QAnimationState::animation() const +{ + Q_D(const QAnimationState); + return d->animation; +} + +/*! + \reimp +*/ +void QAnimationState::onEntry(QEvent *) +{ + Q_D(QAnimationState); + if (d->animation) + d->animation->start(); +} + +/*! + \reimp +*/ +void QAnimationState::onExit(QEvent *) +{ + Q_D(QAnimationState); + if (d->animation) + d->animation->stop(); +} + +/*! + \reimp +*/ +bool QAnimationState::event(QEvent *e) +{ + return QState::event(e); +} + +QT_END_NAMESPACE + +#endif diff --git a/examples/animation/sub-attaq/qanimationstate.h b/examples/animation/sub-attaq/qanimationstate.h new file mode 100644 index 0000000..88c0a6d --- /dev/null +++ b/examples/animation/sub-attaq/qanimationstate.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANIMATIONSTATE_H +#define QANIMATIONSTATE_H + +#ifndef QT_STATEMACHINE_SOLUTION +# include +# include +#else +# include "qstate.h" +# include "qabstractanimation.h" +#endif + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#ifndef QT_NO_ANIMATION + +class QAnimationStatePrivate; + +class QAnimationState : public QState +{ + Q_OBJECT +public: + QAnimationState(QState *parent = 0); + ~QAnimationState(); + + void setAnimation(QAbstractAnimation *animation); + QAbstractAnimation* animation() const; + +Q_SIGNALS: + void animationFinished(); + +protected: + void onEntry(QEvent *); + void onExit(QEvent *); + bool event(QEvent *e); + +private: + Q_DISABLE_COPY(QAnimationState) + Q_DECLARE_PRIVATE(QAnimationState) +}; + +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QANIMATIONSTATE_H diff --git a/examples/animation/sub-attaq/states.cpp b/examples/animation/sub-attaq/states.cpp new file mode 100644 index 0000000..adc8bd0 --- /dev/null +++ b/examples/animation/sub-attaq/states.cpp @@ -0,0 +1,325 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//Own +#include "states.h" +#include "graphicsscene.h" +#include "boat.h" +#include "submarine.h" +#include "torpedo.h" +#include "animationmanager.h" +#include "progressitem.h" + +//Qt +#include +#include +#include +#include +#include +#include + +PlayState::PlayState(GraphicsScene *scene, QState *parent) + : QState(parent), + scene(scene), + machine(0), + currentLevel(0), + score(0) +{ +} + +PlayState::~PlayState() +{ +} + +void PlayState::onEntry(QEvent *) +{ + //We are now playing? + if (machine) { + machine->stop(); + scene->clearScene(); + currentLevel = 0; + score = 0; + delete machine; + } + + machine = new QStateMachine(this); + + //This state is when player is playing + LevelState *levelState = new LevelState(scene, this, machine->rootState()); + + //This state is when the player is actually playing but the game is not paused + QState *playingState = new QState(levelState); + levelState->setInitialState(playingState); + + //This state is when the game is paused + PauseState *pauseState = new PauseState(scene, levelState); + + //We have one view, it receive the key press event + QKeyEventTransition *pressPplay = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P); + pressPplay->setTargetState(pauseState); + QKeyEventTransition *pressPpause = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P); + pressPpause->setTargetState(playingState); + + //Pause "P" is triggered, the player pause the game + playingState->addTransition(pressPplay); + + //To get back playing when the game has been paused + pauseState->addTransition(pressPpause); + + //This state is when player have lost + LostState *lostState = new LostState(scene, this, machine->rootState()); + + //This state is when player have won + WinState *winState = new WinState(scene, this, machine->rootState()); + + //The boat has been destroyed then the game is finished + levelState->addTransition(scene->boat, SIGNAL(boatExecutionFinished()),lostState); + + //This transition check if we won or not + WinTransition *winTransition = new WinTransition(scene, this, winState); + + //The boat has been destroyed then the game is finished + levelState->addTransition(winTransition); + + //This state is an animation when the score changed + UpdateScoreState *scoreState = new UpdateScoreState(this, levelState); + + //This transition update the score when a submarine die + UpdateScoreTransition *scoreTransition = new UpdateScoreTransition(scene, this, levelState); + scoreTransition->setTargetState(scoreState); + + //The boat has been destroyed then the game is finished + playingState->addTransition(scoreTransition); + + //We go back to play state + scoreState->addTransition(playingState); + + //We start playing!!! + machine->setInitialState(levelState); + + //Final state + QFinalState *final = new QFinalState(machine->rootState()); + + //This transition is triggered when the player press space after completing a level + CustomSpaceTransition *spaceTransition = new CustomSpaceTransition(scene->views().at(0), this, QEvent::KeyPress, Qt::Key_Space); + spaceTransition->setTargetState(levelState); + winState->addTransition(spaceTransition); + + //We lost we should reach the final state + lostState->addTransition(lostState, SIGNAL(finished()), final); + + machine->start(); +} + +LevelState::LevelState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game) +{ +} +void LevelState::onEntry(QEvent *) +{ + initializeLevel(); +} + +void LevelState::initializeLevel() +{ + //we re-init the boat + scene->boat->setPos(scene->width()/2, scene->sealLevel() - scene->boat->size().height()); + scene->boat->setCurrentSpeed(0); + scene->boat->setCurrentDirection(Boat::None); + scene->boat->setBombsLaunched(0); + scene->boat->show(); + scene->setFocusItem(scene->boat,Qt::OtherFocusReason); + scene->boat->run(); + + scene->progressItem->setScore(game->score); + scene->progressItem->setLevel(game->currentLevel + 1); + + GraphicsScene::LevelDescription currentLevelDescription = scene->levelsData.value(game->currentLevel); + + for (int i = 0; i < currentLevelDescription.submarines.size(); ++i ) { + + QPair subContent = currentLevelDescription.submarines.at(i); + GraphicsScene::SubmarineDescription submarineDesc = scene->submarinesData.at(subContent.first); + + for (int j = 0; j < subContent.second; ++j ) { + SubMarine *sub = new SubMarine(submarineDesc.type, submarineDesc.name, submarineDesc.points); + scene->addItem(sub); + int random = (qrand() % 15 + 1); + qreal x = random == 13 || random == 5 ? 0 : scene->width() - sub->size().width(); + qreal y = scene->height() -(qrand() % 150 + 1) - sub->size().height(); + sub->setPos(x,y); + sub->setCurrentDirection(x == 0 ? SubMarine::Right : SubMarine::Left); + sub->setCurrentSpeed(qrand() % 3 + 1); + } + } +} + +/** Pause State */ +PauseState::PauseState(GraphicsScene *scene, QState *parent) : QState(parent),scene(scene) +{ +} +void PauseState::onEntry(QEvent *) +{ + AnimationManager::self()->pauseAll(); + scene->boat->setEnabled(false); +} +void PauseState::onExit(QEvent *) +{ + AnimationManager::self()->resumeAll(); + scene->boat->setEnabled(true); + scene->boat->setFocus(); +} + +/** Lost State */ +LostState::LostState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game) +{ +} + +void LostState::onEntry(QEvent *) +{ + //The message to display + QString message = QString("You lose on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score); + + //We set the level back to 0 + game->currentLevel = 0; + + //We set the score back to 0 + game->score = 0; + + //We clear the scene + scene->clearScene(); + + //we have only one view + QMessageBox::information(scene->views().at(0),"You lose",message); +} + +/** Win State */ +WinState::WinState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game) +{ +} + +void WinState::onEntry(QEvent *) +{ + //We clear the scene + scene->clearScene(); + + QString message; + if (scene->levelsData.size() - 1 != game->currentLevel) { + message = QString("You win the level %1. Your score is %2.\nPress Space to continue after closing this dialog.").arg(game->currentLevel+1).arg(game->score); + //We increment the level number + game->currentLevel++; + } else { + message = QString("You finish the game on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score); + //We set the level back to 0 + game->currentLevel = 0; + //We set the score back to 0 + game->score = 0; + } + + //we have only one view + QMessageBox::information(scene->views().at(0),"You win",message); +} + +/** UpdateScore State */ +UpdateScoreState::UpdateScoreState(PlayState *game, QState *parent) : QState(parent) +{ + this->game = game; +} +void UpdateScoreState::onEntry(QEvent *e) +{ + QState::onEntry(e); +} + +/** Win transition */ +UpdateScoreTransition::UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) + : QSignalTransition(scene,SIGNAL(subMarineDestroyed(int)), QList() << target), + game(game), scene(scene) +{ +} + +bool UpdateScoreTransition::eventTest(QEvent *event) +{ + if (!QSignalTransition::eventTest(event)) + return false; + else { + QSignalEvent *se = static_cast(event); + game->score += se->arguments().at(0).toInt(); + scene->progressItem->setScore(game->score); + return true; + } +} + +/** Win transition */ +WinTransition::WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) + : QSignalTransition(scene,SIGNAL(allSubMarineDestroyed(int)), QList() << target), + game(game), scene(scene) +{ +} + +bool WinTransition::eventTest(QEvent *event) +{ + if (!QSignalTransition::eventTest(event)) + return false; + else { + QSignalEvent *se = static_cast(event); + game->score += se->arguments().at(0).toInt(); + scene->progressItem->setScore(game->score); + return true; + } +} + +/** Space transition */ +CustomSpaceTransition::CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key) + : QKeyEventTransition(widget, type, key), + game(game) +{ +} + +bool CustomSpaceTransition::eventTest(QEvent *event) +{ + Q_UNUSED(event); + if (!QKeyEventTransition::eventTest(event)) + return false; + if (game->currentLevel != 0) + return true; + else + return false; + +} diff --git a/examples/animation/sub-attaq/states.h b/examples/animation/sub-attaq/states.h new file mode 100644 index 0000000..71375e0 --- /dev/null +++ b/examples/animation/sub-attaq/states.h @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef STATES_H +#define STATES_H + +//Qt +#include +#include +#include +#include +#include + +class GraphicsScene; +class Boat; +class SubMarine; +QT_BEGIN_NAMESPACE +class QStateMachine; +QT_END_NAMESPACE + +class PlayState : public QState +{ +public: + PlayState(GraphicsScene *scene, QState *parent = 0); + ~PlayState(); + + protected: + void onEntry(QEvent *); + +private : + GraphicsScene *scene; + QStateMachine *machine; + int currentLevel; + int score; + QState *parallelChild; + + friend class UpdateScoreState; + friend class UpdateScoreTransition; + friend class WinTransition; + friend class CustomSpaceTransition; + friend class WinState; + friend class LostState; + friend class LevelState; +}; + +class LevelState : public QState +{ +public: + LevelState(GraphicsScene *scene, PlayState *game, QState *parent = 0); +protected: + void onEntry(QEvent *); +private : + void initializeLevel(); + GraphicsScene *scene; + PlayState *game; +}; + +class PauseState : public QState +{ +public: + PauseState(GraphicsScene *scene, QState *parent = 0); + +protected: + void onEntry(QEvent *); + void onExit(QEvent *); +private : + GraphicsScene *scene; + Boat *boat; +}; + +class LostState : public QState +{ +public: + LostState(GraphicsScene *scene, PlayState *game, QState *parent = 0); + +protected: + void onEntry(QEvent *); +private : + GraphicsScene *scene; + PlayState *game; +}; + +class WinState : public QState +{ +public: + WinState(GraphicsScene *scene, PlayState *game, QState *parent = 0); + +protected: + void onEntry(QEvent *); +private : + GraphicsScene *scene; + PlayState *game; +}; + +class UpdateScoreState : public QState +{ +public: + UpdateScoreState(PlayState *game, QState *parent); +protected: + void onEntry(QEvent *); +private: + QPropertyAnimation *scoreAnimation; + PlayState *game; +}; + +//These transtion is used to update the score +class UpdateScoreTransition : public QSignalTransition +{ +public: + UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target); +protected: + virtual bool eventTest(QEvent *event); +private: + PlayState * game; + GraphicsScene *scene; +}; + +//These transtion test if we have won the game +class WinTransition : public QSignalTransition +{ +public: + WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target); +protected: + virtual bool eventTest(QEvent *event); +private: + PlayState * game; + GraphicsScene *scene; +}; + +//These transtion is true if one level has been completed and the player want to continue + class CustomSpaceTransition : public QKeyEventTransition +{ +public: + CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key); +protected: + virtual bool eventTest(QEvent *event); +private: + PlayState *game; + int key; +}; + +#endif // STATES_H diff --git a/examples/animation/sub-attaq/sub-attaq.pro b/examples/animation/sub-attaq/sub-attaq.pro new file mode 100644 index 0000000..d13a099 --- /dev/null +++ b/examples/animation/sub-attaq/sub-attaq.pro @@ -0,0 +1,36 @@ +contains(QT_CONFIG, opengl):QT += opengl + +HEADERS += boat.h \ + bomb.h \ + mainwindow.h \ + submarine.h \ + torpedo.h \ + pixmapitem.h \ + graphicsscene.h \ + animationmanager.h \ + states.h \ + boat_p.h \ + submarine_p.h \ + custompropertyanimation.h \ + qanimationstate.h \ + progressitem.h +SOURCES += boat.cpp \ + bomb.cpp \ + main.cpp \ + mainwindow.cpp \ + submarine.cpp \ + torpedo.cpp \ + pixmapitem.cpp \ + graphicsscene.cpp \ + animationmanager.cpp \ + states.cpp \ + custompropertyanimation.cpp \ + qanimationstate.cpp \ + progressitem.cpp +RESOURCES += subattaq.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/animation/sub-attaq +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS sub-attaq.pro pics +sources.path = $$[QT_INSTALL_EXAMPLES]/animation/sub-attaq +INSTALLS += target sources diff --git a/examples/animation/sub-attaq/subattaq.qrc b/examples/animation/sub-attaq/subattaq.qrc new file mode 100644 index 0000000..c76f8ef --- /dev/null +++ b/examples/animation/sub-attaq/subattaq.qrc @@ -0,0 +1,38 @@ + + + pics/scalable/sub-attaq.svg + pics/scalable/submarine.svg + pics/scalable/boat.svg + pics/scalable/torpedo.svg + pics/welcome/logo-s.png + pics/welcome/logo-u.png + pics/welcome/logo-b.png + pics/welcome/logo-dash.png + pics/welcome/logo-a.png + pics/welcome/logo-t.png + pics/welcome/logo-t2.png + pics/welcome/logo-a2.png + pics/welcome/logo-q.png + pics/welcome/logo-excl.png + pics/big/background.png + pics/big/boat.png + pics/big/bomb.png + pics/big/submarine.png + pics/big/surface.png + pics/big/torpedo.png + pics/small/background.png + pics/small/boat.png + pics/small/bomb.png + pics/small/submarine.png + pics/small/surface.png + pics/small/torpedo.png + pics/big/explosion/boat/step1.png + pics/big/explosion/boat/step2.png + pics/big/explosion/boat/step3.png + pics/big/explosion/boat/step4.png + pics/big/explosion/submarine/step1.png + pics/big/explosion/submarine/step2.png + pics/big/explosion/submarine/step3.png + pics/big/explosion/submarine/step4.png + + diff --git a/examples/animation/sub-attaq/submarine.cpp b/examples/animation/sub-attaq/submarine.cpp new file mode 100644 index 0000000..d8cf1da --- /dev/null +++ b/examples/animation/sub-attaq/submarine.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//Own +#include "submarine.h" +#include "submarine_p.h" +#include "torpedo.h" +#include "pixmapitem.h" +#include "graphicsscene.h" +#include "animationmanager.h" +#include "custompropertyanimation.h" +#include "qanimationstate.h" + +#include +#include +#include +#include + +static QAbstractAnimation *setupDestroyAnimation(SubMarine *sub) +{ + QSequentialAnimationGroup *group = new QSequentialAnimationGroup(sub); +#if QT_VERSION >=0x040500 + PixmapItem *step1 = new PixmapItem(QString("explosion/submarine/step1"),GraphicsScene::Big, sub); + step1->setZValue(6); + PixmapItem *step2 = new PixmapItem(QString("explosion/submarine/step2"),GraphicsScene::Big, sub); + step2->setZValue(6); + PixmapItem *step3 = new PixmapItem(QString("explosion/submarine/step3"),GraphicsScene::Big, sub); + step3->setZValue(6); + PixmapItem *step4 = new PixmapItem(QString("explosion/submarine/step4"),GraphicsScene::Big, sub); + step4->setZValue(6); + step1->setOpacity(0); + step2->setOpacity(0); + step3->setOpacity(0); + step4->setOpacity(0); + CustomPropertyAnimation *anim1 = new CustomPropertyAnimation(sub); + anim1->setMemberFunctions((QGraphicsItem*)step1, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim1->setDuration(100); + anim1->setEndValue(1); + CustomPropertyAnimation *anim2 = new CustomPropertyAnimation(sub); + anim2->setMemberFunctions((QGraphicsItem*)step2, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim2->setDuration(100); + anim2->setEndValue(1); + CustomPropertyAnimation *anim3 = new CustomPropertyAnimation(sub); + anim3->setMemberFunctions((QGraphicsItem*)step3, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim3->setDuration(100); + anim3->setEndValue(1); + CustomPropertyAnimation *anim4 = new CustomPropertyAnimation(sub); + anim4->setMemberFunctions((QGraphicsItem*)step4, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); + anim4->setDuration(100); + anim4->setEndValue(1); + group->addAnimation(anim1); + group->addAnimation(anim2); + group->addAnimation(anim3); + group->addAnimation(anim4); +#else + // work around for a bug where we don't transition if the duration is zero. + QtPauseAnimation *anim = new QtPauseAnimation(group); + anim->setDuration(1); + group->addAnimation(anim); +#endif + AnimationManager::self()->registerAnimation(group); + return group; +} + + +SubMarine::SubMarine(int type, const QString &name, int points, QGraphicsItem * parent, Qt::WindowFlags wFlags) + : QGraphicsWidget(parent,wFlags), subType(type), subName(name), subPoints(points), speed(0), direction(SubMarine::None) +{ + pixmapItem = new PixmapItem(QString("submarine"),GraphicsScene::Big, this); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setZValue(5); + setFlags(QGraphicsItem::ItemIsMovable); + resize(pixmapItem->boundingRect().width(),pixmapItem->boundingRect().height()); + setTransformOrigin(boundingRect().center()); + + //We setup the state machine of the submarine + QStateMachine *machine = new QStateMachine(this); + + //This state is when the boat is moving/rotating + QState *moving = new QState(machine->rootState()); + + //This state is when the boat is moving from left to right + MovementState *movement = new MovementState(this, moving); + + //This state is when the boat is moving from left to right + ReturnState *rotation = new ReturnState(this, moving); + + //This is the initial state of the moving root state + moving->setInitialState(movement); + + movement->addTransition(this, SIGNAL(subMarineStateChanged()), moving); + + //This is the initial state of the machine + machine->setInitialState(moving); + + //End + QFinalState *final = new QFinalState(machine->rootState()); + + //If the moving animation is finished we move to the return state + movement->addTransition(movement, SIGNAL(animationFinished()), rotation); + + //If the return animation is finished we move to the moving state + rotation->addTransition(rotation, SIGNAL(animationFinished()), movement); + + //This state play the destroyed animation + QAnimationState *destroyedState = new QAnimationState(machine->rootState()); + destroyedState->setAnimation(setupDestroyAnimation(this)); + + //Play a nice animation when the submarine is destroyed + moving->addTransition(this, SIGNAL(subMarineDestroyed()), destroyedState); + + //Transition to final state when the destroyed animation is finished + destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final); + + //The machine has finished to be executed, then the submarine is dead + connect(machine,SIGNAL(finished()),this, SIGNAL(subMarineExecutionFinished())); + + machine->start(); +} + +int SubMarine::points() +{ + return subPoints; +} + +void SubMarine::setCurrentDirection(SubMarine::Movement direction) +{ + if (this->direction == direction) + return; + if (direction == SubMarine::Right && this->direction == SubMarine::None) { + setYRotation(180); + } + this->direction = direction; +} + +enum SubMarine::Movement SubMarine::currentDirection() const +{ + return direction; +} + +void SubMarine::setCurrentSpeed(int speed) +{ + if (speed < 0 || speed > 3) { + qWarning("SubMarine::setCurrentSpeed : The speed is invalid"); + } + this->speed = speed; + emit subMarineStateChanged(); +} + +int SubMarine::currentSpeed() const +{ + return speed; +} + +void SubMarine::launchTorpedo(int speed) +{ + Torpedo * torp = new Torpedo(); + GraphicsScene *scene = static_cast(this->scene()); + scene->addItem(torp); + torp->setPos(x(), y()); + torp->setCurrentSpeed(speed); + torp->launch(); +} + +void SubMarine::destroy() +{ + emit subMarineDestroyed(); +} + +int SubMarine::type() const +{ + return Type; +} diff --git a/examples/animation/sub-attaq/submarine.h b/examples/animation/sub-attaq/submarine.h new file mode 100644 index 0000000..4001603 --- /dev/null +++ b/examples/animation/sub-attaq/submarine.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __SUBMARINE__H__ +#define __SUBMARINE__H__ + +//Qt +#include +#include + +class PixmapItem; + +class Torpedo; + +class SubMarine : public QGraphicsWidget +{ +Q_OBJECT +public: + enum Movement { + None = 0, + Left, + Right + }; + enum { Type = UserType + 1 }; + SubMarine(int type, const QString &name, int points, QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); + + int points(); + + void setCurrentDirection(Movement direction); + enum Movement currentDirection() const; + + void setCurrentSpeed(int speed); + int currentSpeed() const; + + void launchTorpedo(int speed); + void destroy(); + + virtual int type() const; + +Q_SIGNALS: + void subMarineDestroyed(); + void subMarineExecutionFinished(); + void subMarineStateChanged(); + +private: + int subType; + QString subName; + int subPoints; + int speed; + Movement direction; + PixmapItem *pixmapItem; +}; + +#endif //__SUBMARINE__H__ diff --git a/examples/animation/sub-attaq/submarine_p.h b/examples/animation/sub-attaq/submarine_p.h new file mode 100644 index 0000000..8c31eb7 --- /dev/null +++ b/examples/animation/sub-attaq/submarine_p.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SUBMARINE_P_H +#define SUBMARINE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +//Own +#include "animationmanager.h" +#include "submarine.h" +#include "qanimationstate.h" + +//Qt +#include +#include + +//This state is describing when the boat is moving right +class MovementState : public QAnimationState +{ +Q_OBJECT +public: + MovementState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent) + { + movementAnimation = new QPropertyAnimation(submarine, "pos"); + connect(movementAnimation,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationMovementValueChanged(const QVariant &))); + setAnimation(movementAnimation); + AnimationManager::self()->registerAnimation(movementAnimation); + this->submarine = submarine; + } + +protected slots: + void onAnimationMovementValueChanged(const QVariant &) + { + if (qrand() % 200 + 1 == 3) + submarine->launchTorpedo(qrand() % 3 + 1); + } + +protected: + void onEntry(QEvent *e) + { + if (submarine->currentDirection() == SubMarine::Left) { + movementAnimation->setEndValue(QPointF(0,submarine->y())); + movementAnimation->setDuration(submarine->x()/submarine->currentSpeed()*12); + } + else /*if (submarine->currentDirection() == SubMarine::Right)*/ { + movementAnimation->setEndValue(QPointF(submarine->scene()->width()-submarine->size().width(),submarine->y())); + movementAnimation->setDuration((submarine->scene()->width()-submarine->size().width()-submarine->x())/submarine->currentSpeed()*12); + } + movementAnimation->setStartValue(submarine->pos()); + QAnimationState::onEntry(e); + } + +private: + SubMarine *submarine; + QPropertyAnimation *movementAnimation; +}; + +//This state is describing when the boat is moving right +class ReturnState : public QAnimationState +{ +public: + ReturnState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent) + { + returnAnimation = new QPropertyAnimation(submarine, "yRotation"); + AnimationManager::self()->registerAnimation(returnAnimation); + setAnimation(returnAnimation); + this->submarine = submarine; + } + +protected: + void onEntry(QEvent *e) + { + returnAnimation->stop(); + returnAnimation->setStartValue(submarine->yRotation()); + returnAnimation->setEndValue(submarine->currentDirection() == SubMarine::Right ? 360. : 180.); + returnAnimation->setDuration(500); + QAnimationState::onEntry(e); + } + + void onExit(QEvent *e) + { + submarine->currentDirection() == SubMarine::Right ? submarine->setCurrentDirection(SubMarine::Left) : submarine->setCurrentDirection(SubMarine::Right); + QAnimationState::onExit(e); + } + +private: + SubMarine *submarine; + QPropertyAnimation *returnAnimation; +}; + +#endif // SUBMARINE_P_H diff --git a/examples/animation/sub-attaq/torpedo.cpp b/examples/animation/sub-attaq/torpedo.cpp new file mode 100644 index 0000000..02a54fc --- /dev/null +++ b/examples/animation/sub-attaq/torpedo.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//Own +#include "torpedo.h" +#include "pixmapitem.h" +#include "boat.h" +#include "graphicsscene.h" +#include "animationmanager.h" +#include "qanimationstate.h" + +#include +#include +#include + +Torpedo::Torpedo(QGraphicsItem * parent, Qt::WindowFlags wFlags) + : QGraphicsWidget(parent,wFlags), currentSpeed(0), launchAnimation(0) +{ + pixmapItem = new PixmapItem(QString::fromLatin1("torpedo"),GraphicsScene::Big, this); + setZValue(2); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + setFlags(QGraphicsItem::ItemIsMovable); + resize(pixmapItem->boundingRect().size()); +} + +void Torpedo::launch() +{ + launchAnimation = new QPropertyAnimation(this, "pos"); + AnimationManager::self()->registerAnimation(launchAnimation); + launchAnimation->setEndValue(QPointF(x(),qobject_cast(scene())->sealLevel() - 15)); + launchAnimation->setEasingCurve(QEasingCurve::InQuad); + launchAnimation->setDuration(y()/currentSpeed*10); + connect(launchAnimation,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationLaunchValueChanged(const QVariant &))); + + //We setup the state machine of the torpedo + QStateMachine *machine = new QStateMachine(this); + + //This state is when the launch animation is playing + QAnimationState *launched = new QAnimationState(machine->rootState()); + launched->setAnimation(launchAnimation); + + //End + QFinalState *final = new QFinalState(machine->rootState()); + + machine->setInitialState(launched); + + //### Add a nice animation when the torpedo is destroyed + launched->addTransition(this, SIGNAL(torpedoExplosed()),final); + + //If the animation is finished, then we move to the final state + launched->addTransition(launched, SIGNAL(animationFinished()), final); + + //The machine has finished to be executed, then the boat is dead + connect(machine,SIGNAL(finished()),this, SIGNAL(torpedoExecutionFinished())); + + machine->start(); +} + +void Torpedo::setCurrentSpeed(int speed) +{ + if (speed < 0) { + qWarning("Torpedo::setCurrentSpeed : The speed is invalid"); + return; + } + currentSpeed = speed; +} + +void Torpedo::onAnimationLaunchValueChanged(const QVariant &) +{ + foreach (QGraphicsItem *item , collidingItems(Qt::IntersectsItemBoundingRect)) { + if (item->type() == Boat::Type) { + Boat *b = static_cast(item); + b->destroy(); + } + } +} + +void Torpedo::destroy() +{ + launchAnimation->stop(); + emit torpedoExplosed(); +} diff --git a/examples/animation/sub-attaq/torpedo.h b/examples/animation/sub-attaq/torpedo.h new file mode 100644 index 0000000..4a0f457 --- /dev/null +++ b/examples/animation/sub-attaq/torpedo.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __TORPEDO__H__ +#define __TORPEDO__H__ + +//Qt +#include + +#include +#include + +class PixmapItem; + +class Torpedo : public QGraphicsWidget +{ +Q_OBJECT +Q_PROPERTY(QPointF pos READ pos WRITE setPos) +public: + Torpedo(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); + void launch(); + void setCurrentSpeed(int speed); + void destroy(); + +Q_SIGNALS: + void torpedoExplosed(); + void torpedoExecutionFinished(); + +private slots: + void onAnimationLaunchValueChanged(const QVariant &); + +private: + int currentSpeed; + PixmapItem *pixmapItem; + QVariantAnimation *launchAnimation; +}; + +#endif //__TORPEDO__H__ diff --git a/examples/examples.pro b/examples/examples.pro index 41501a0..bfcf9b4 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs SUBDIRS = \ + animation \ desktop \ dialogs \ draganddrop \ @@ -14,6 +15,7 @@ SUBDIRS = \ qtconcurrent \ richtext \ sql \ + statemachine \ threads \ tools \ tutorials \ diff --git a/examples/statemachine/README b/examples/statemachine/README new file mode 100644 index 0000000..2879e67 --- /dev/null +++ b/examples/statemachine/README @@ -0,0 +1,36 @@ +Qt is provided with a powerful hierchical finite state machine through +the Qt State Machine classes. + +The example launcher provided with Qt can be used to explore each of the +examples in this directory. + +Documentation for these examples can be found via the Tutorial and Examples +link in the main Qt documentation. + + +Finding the Qt Examples and Demos launcher +========================================== + +On Windows: + +The launcher can be accessed via the Windows Start menu. Select the menu +entry entitled "Qt Examples and Demos" entry in the submenu containing +the Qt tools. + +On Mac OS X: + +For the binary distribution, the qtdemo executable is installed in the +/Developer/Applications/Qt directory. For the source distribution, it is +installed alongside the other Qt tools on the path specified when Qt is +configured. + +On Unix/Linux: + +The qtdemo executable is installed alongside the other Qt tools on the path +specified when Qt is configured. + +On all platforms: + +The source code for the launcher can be found in the demos/qtdemo directory +in the Qt package. This example is built at the same time as the Qt libraries, +tools, examples, and demonstrations. diff --git a/examples/statemachine/eventtransitions/eventtransitions.pro b/examples/statemachine/eventtransitions/eventtransitions.pro new file mode 100644 index 0000000..7e92cf2 --- /dev/null +++ b/examples/statemachine/eventtransitions/eventtransitions.pro @@ -0,0 +1,7 @@ +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/eventtransitions +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS eventtransitions.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/eventtransitions +INSTALLS += target sources diff --git a/examples/statemachine/eventtransitions/main.cpp b/examples/statemachine/eventtransitions/main.cpp new file mode 100644 index 0000000..aba0c73 --- /dev/null +++ b/examples/statemachine/eventtransitions/main.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#ifdef QT_STATEMACHINE_SOLUTION +#include +#include +#include +#endif + +//! [0] +class Window : public QWidget +{ +public: + Window(QWidget *parent = 0) + : QWidget(parent) + { + QPushButton *button = new QPushButton(this); + button->setGeometry(QRect(100, 100, 100, 100)); +//! [0] + +//! [1] + QStateMachine *machine = new QStateMachine(this); + + QState *s1 = new QState(); + s1->assignProperty(button, "text", "Outside"); + + QState *s2 = new QState(); + s2->assignProperty(button, "text", "Inside"); +//! [1] + +//! [2] + QEventTransition *enterTransition = new QEventTransition(button, QEvent::Enter); + enterTransition->setTargetState(s2); + s1->addTransition(enterTransition); +//! [2] + +//! [3] + QEventTransition *leaveTransition = new QEventTransition(button, QEvent::Leave); + leaveTransition->setTargetState(s1); + s2->addTransition(leaveTransition); +//! [3] + +//! [4] + QState *s3 = new QState(); + s3->assignProperty(button, "text", "Pressing..."); + + QEventTransition *pressTransition = new QEventTransition(button, QEvent::MouseButtonPress); + pressTransition->setTargetState(s3); + s2->addTransition(pressTransition); + + QEventTransition *releaseTransition = new QEventTransition(button, QEvent::MouseButtonRelease); + releaseTransition->setTargetState(s2); + s3->addTransition(releaseTransition); +//! [4] + +//! [5] + machine->addState(s1); + machine->addState(s2); + machine->addState(s3); + + machine->setInitialState(s1); + machine->start(); + } +}; +//! [5] + +//! [6] +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Window window; + window.resize(300, 300); + window.show(); + + return app.exec(); +} +//! [6] diff --git a/examples/statemachine/factorial/factorial.pro b/examples/statemachine/factorial/factorial.pro new file mode 100644 index 0000000..14a6833 --- /dev/null +++ b/examples/statemachine/factorial/factorial.pro @@ -0,0 +1,11 @@ +QT = core +win32: CONFIG += console +mac:CONFIG -= app_bundle + +SOURCES += main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/factorial +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS factorial.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/factorial +INSTALLS += target sources diff --git a/examples/statemachine/factorial/main.cpp b/examples/statemachine/factorial/main.cpp new file mode 100644 index 0000000..1065eb8 --- /dev/null +++ b/examples/statemachine/factorial/main.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#ifdef QT_STATEMACHINE_SOLUTION +#include +#include +#include +#include +#endif + +//! [0] +class Factorial : public QObject +{ + Q_OBJECT + Q_PROPERTY(int x READ x WRITE setX) + Q_PROPERTY(int fac READ fac WRITE setFac) +public: + Factorial(QObject *parent = 0) + : QObject(parent), m_x(-1), m_fac(1) + { + } + + int x() const + { + return m_x; + } + + void setX(int x) + { + if (x == m_x) + return; + m_x = x; + emit xChanged(x); + } + + int fac() const + { + return m_fac; + } + + void setFac(int fac) + { + m_fac = fac; + } + +Q_SIGNALS: + void xChanged(int value); + +private: + int m_x; + int m_fac; +}; +//! [0] + +//! [1] +class FactorialLoopTransition : public QSignalTransition +{ +public: + FactorialLoopTransition(Factorial *fact) + : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact) + {} + + virtual bool eventTest(QEvent *e) + { + if (!QSignalTransition::eventTest(e)) + return false; + QSignalEvent *se = static_cast(e); + return se->arguments().at(0).toInt() > 1; + } + + virtual void onTransition(QEvent *e) + { + QSignalEvent *se = static_cast(e); + int x = se->arguments().at(0).toInt(); + int fac = m_fact->property("fac").toInt(); + m_fact->setProperty("fac", x * fac); + m_fact->setProperty("x", x - 1); + } + +private: + Factorial *m_fact; +}; +//! [1] + +//! [2] +class FactorialDoneTransition : public QSignalTransition +{ +public: + FactorialDoneTransition(Factorial *fact) + : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact) + {} + + virtual bool eventTest(QEvent *e) + { + if (!QSignalTransition::eventTest(e)) + return false; + QSignalEvent *se = static_cast(e); + return se->arguments().at(0).toInt() <= 1; + } + + virtual void onTransition(QEvent *) + { + fprintf(stdout, "%d\n", m_fact->property("fac").toInt()); + } + +private: + Factorial *m_fact; +}; +//! [2] + +//! [3] +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + Factorial factorial; + QStateMachine machine; +//! [3] + +//! [4] + QState *compute = new QState(machine.rootState()); + compute->assignProperty(&factorial, "fac", 1); + compute->assignProperty(&factorial, "x", 6); + compute->addTransition(new FactorialLoopTransition(&factorial)); +//! [4] + +//! [5] + QFinalState *done = new QFinalState(machine.rootState()); + FactorialDoneTransition *doneTransition = new FactorialDoneTransition(&factorial); + doneTransition->setTargetState(done); + compute->addTransition(doneTransition); +//! [5] + +//! [6] + machine.setInitialState(compute); + QObject::connect(&machine, SIGNAL(finished()), &app, SLOT(quit())); + machine.start(); + + return app.exec(); +} +//! [6] + +#include "main.moc" diff --git a/examples/statemachine/pingpong/main.cpp b/examples/statemachine/pingpong/main.cpp new file mode 100644 index 0000000..331627e --- /dev/null +++ b/examples/statemachine/pingpong/main.cpp @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#ifdef QT_STATEMACHINE_SOLUTION +#include +#include +#include +#endif + +//! [0] +class PingEvent : public QEvent +{ +public: + PingEvent() : QEvent(QEvent::Type(QEvent::User+2)) + {} +}; + +class PongEvent : public QEvent +{ +public: + PongEvent() : QEvent(QEvent::Type(QEvent::User+3)) + {} +}; +//! [0] + +//! [1] +class Pinger : public QState +{ +public: + Pinger(QState *parent) + : QState(parent) {} + +protected: + virtual void onEntry(QEvent *) + { + machine()->postEvent(new PingEvent()); + fprintf(stdout, "ping?\n"); + } +}; +//! [1] + +//! [3] +class PongTransition : public QAbstractTransition +{ +public: + PongTransition() {} + +protected: + virtual bool eventTest(QEvent *e) { + return (e->type() == QEvent::User+3); + } + virtual void onTransition(QEvent *) + { + machine()->postEvent(new PingEvent(), 500); + fprintf(stdout, "ping?\n"); + } +}; +//! [3] + +//! [2] +class PingTransition : public QAbstractTransition +{ +public: + PingTransition() {} + +protected: + virtual bool eventTest(QEvent *e) { + return (e->type() == QEvent::User+2); + } + virtual void onTransition(QEvent *) + { + machine()->postEvent(new PongEvent(), 500); + fprintf(stdout, "pong!\n"); + } +}; +//! [2] + +//! [4] +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + QStateMachine machine; + QState *group = new QState(QState::ParallelStates); + group->setObjectName("group"); +//! [4] + +//! [5] + Pinger *pinger = new Pinger(group); + pinger->setObjectName("pinger"); + pinger->addTransition(new PongTransition()); + + QState *ponger = new QState(group); + ponger->setObjectName("ponger"); + ponger->addTransition(new PingTransition()); +//! [5] + +//! [6] + machine.addState(group); + machine.setInitialState(group); + machine.start(); + + return app.exec(); +} +//! [6] diff --git a/examples/statemachine/pingpong/pingpong.pro b/examples/statemachine/pingpong/pingpong.pro new file mode 100644 index 0000000..42eab6c --- /dev/null +++ b/examples/statemachine/pingpong/pingpong.pro @@ -0,0 +1,11 @@ +QT = core +win32: CONFIG += console +mac:CONFIG -= app_bundle + +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/pingpong +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS pingpong.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/pingpong +INSTALLS += target sources diff --git a/examples/statemachine/statemachine.pro b/examples/statemachine/statemachine.pro new file mode 100644 index 0000000..5074a3c --- /dev/null +++ b/examples/statemachine/statemachine.pro @@ -0,0 +1,15 @@ +TEMPLATE = subdirs +SUBDIRS = \ + eventtransitions \ + factorial \ + pingpong \ + trafficlight \ + twowaybutton \ + tankgame \ + tankgameplugins + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS statemachine.pro README +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine +INSTALLS += target sources diff --git a/examples/statemachine/tankgame/gameitem.cpp b/examples/statemachine/tankgame/gameitem.cpp new file mode 100644 index 0000000..ad8b37c --- /dev/null +++ b/examples/statemachine/tankgame/gameitem.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gameitem.h" + +#include +#include + +GameItem::GameItem(QObject *parent) : QObject(parent) +{ +} + +QPointF GameItem::tryMove(const QPointF &requestedPosition, QLineF *collidedLine, + QGraphicsItem **collidedItem) const +{ + QLineF movementPath(pos(), requestedPosition); + + qreal cannonLength = 0.0; + { + QPointF p1 = boundingRect().center(); + QPointF p2 = QPointF(boundingRect().right() + 10.0, p1.y()); + + cannonLength = QLineF(mapToScene(p1), mapToScene(p2)).length(); + } + + movementPath.setLength(movementPath.length() + cannonLength); + + QRectF boundingRectPath(QPointF(qMin(movementPath.x1(), movementPath.x2()), qMin(movementPath.y1(), movementPath.y2())), + QPointF(qMax(movementPath.x1(), movementPath.x2()), qMax(movementPath.y1(), movementPath.y2()))); + + QList itemsInRect = scene()->items(boundingRectPath, Qt::IntersectsItemBoundingRect); + + QPointF nextPoint = requestedPosition; + QRectF sceneRect = scene()->sceneRect(); + + foreach (QGraphicsItem *item, itemsInRect) { + if (item == static_cast(this)) + continue; + + QPolygonF mappedBoundingRect = item->mapToScene(item->boundingRect()); + for (int i=0; isceneRect().topLeft(), scene()->sceneRect().bottomLeft()); + } + + if (nextPoint.x() > sceneRect.right()) { + nextPoint.rx() = sceneRect.right(); + if (collidedLine != 0) + *collidedLine = QLineF(scene()->sceneRect().topRight(), scene()->sceneRect().bottomRight()); + } + + if (nextPoint.y() < sceneRect.top()) { + nextPoint.ry() = sceneRect.top(); + if (collidedLine != 0) + *collidedLine = QLineF(scene()->sceneRect().topLeft(), scene()->sceneRect().topRight()); + } + + if (nextPoint.y() > sceneRect.bottom()) { + nextPoint.ry() = sceneRect.bottom(); + if (collidedLine != 0) + *collidedLine = QLineF(scene()->sceneRect().bottomLeft(), scene()->sceneRect().bottomRight()); + } + + return nextPoint; +} + diff --git a/examples/statemachine/tankgame/gameitem.h b/examples/statemachine/tankgame/gameitem.h new file mode 100644 index 0000000..90b0a6c --- /dev/null +++ b/examples/statemachine/tankgame/gameitem.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GAMEITEM_H +#define GAMEITEM_H + +#include + +QT_BEGIN_NAMESPACE +class QLineF; +QT_END_NAMESPACE +class GameItem: public QObject, public QGraphicsItem +{ + Q_OBJECT +public: + enum { Type = UserType + 1 }; + int type() const { return Type; } + + GameItem(QObject *parent = 0); + + virtual void idle(qreal elapsed) = 0; + +protected: + QPointF tryMove(const QPointF &requestedPosition, QLineF *collidedLine = 0, + QGraphicsItem **collidedItem = 0) const; +}; + +#endif diff --git a/examples/statemachine/tankgame/gameovertransition.cpp b/examples/statemachine/tankgame/gameovertransition.cpp new file mode 100644 index 0000000..360e902 --- /dev/null +++ b/examples/statemachine/tankgame/gameovertransition.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gameovertransition.h" +#include "tankitem.h" + +#include +#include + +GameOverTransition::GameOverTransition(QAbstractState *targetState) + : QSignalTransition(new QSignalMapper(), SIGNAL(mapped(QObject*))) +{ + setTargetState(targetState); + + QSignalMapper *mapper = qobject_cast(senderObject()); + mapper->setParent(this); +} + +void GameOverTransition::addTankItem(TankItem *tankItem) +{ + m_tankItems.append(tankItem); + + QSignalMapper *mapper = qobject_cast(senderObject()); + mapper->setMapping(tankItem, tankItem); + connect(tankItem, SIGNAL(aboutToBeDestroyed()), mapper, SLOT(map())); +} + +bool GameOverTransition::eventTest(QEvent *e) +{ + bool ret = QSignalTransition::eventTest(e); + + if (ret) { + QSignalEvent *signalEvent = static_cast(e); + QObject *sender = qvariant_cast(signalEvent->arguments().at(0)); + TankItem *tankItem = qobject_cast(sender); + m_tankItems.removeAll(tankItem); + + return m_tankItems.size() <= 1; + } else { + return false; + } +} diff --git a/examples/statemachine/tankgame/gameovertransition.h b/examples/statemachine/tankgame/gameovertransition.h new file mode 100644 index 0000000..5e99a75 --- /dev/null +++ b/examples/statemachine/tankgame/gameovertransition.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GAMEOVERTRANSITION_H +#define GAMEOVERTRANSITION_H + +#include + +class TankItem; +class GameOverTransition: public QSignalTransition +{ + Q_OBJECT +public: + GameOverTransition(QAbstractState *targetState); + + void addTankItem(TankItem *tankItem); + +protected: + bool eventTest(QEvent *event); + +private: + QList m_tankItems; +}; + +#endif diff --git a/examples/statemachine/tankgame/main.cpp b/examples/statemachine/tankgame/main.cpp new file mode 100644 index 0000000..185ad68 --- /dev/null +++ b/examples/statemachine/tankgame/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "mainwindow.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + MainWindow mainWindow; + mainWindow.show(); + + return app.exec(); +} diff --git a/examples/statemachine/tankgame/mainwindow.cpp b/examples/statemachine/tankgame/mainwindow.cpp new file mode 100644 index 0000000..46e0db3 --- /dev/null +++ b/examples/statemachine/tankgame/mainwindow.cpp @@ -0,0 +1,342 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include "tankitem.h" +#include "rocketitem.h" +#include "plugin.h" +#include "gameovertransition.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), m_scene(0), m_machine(0), m_runningState(0), m_started(false) +{ + init(); +} + +MainWindow::~MainWindow() +{ +} + +void MainWindow::addWall(const QRectF &wall) +{ + QGraphicsRectItem *item = new QGraphicsRectItem; + item->setRect(wall); + item->setBrush(Qt::darkGreen); + item->setPen(QPen(Qt::black, 0)); + + m_scene->addItem(item); +} + +void MainWindow::init() +{ + setWindowTitle("Pluggable Tank Game"); + + QGraphicsView *view = new QGraphicsView(this); + view->setRenderHints(QPainter::Antialiasing); + setCentralWidget(view); + + m_scene = new QGraphicsScene(this); + view->setScene(m_scene); + + QRectF sceneRect = QRectF(-200.0, -200.0, 400.0, 400.0); + m_scene->setSceneRect(sceneRect); + + { + TankItem *item = new TankItem(this); + + item->setPos(m_scene->sceneRect().topLeft() + QPointF(30.0, 30.0)); + item->setDirection(45.0); + item->setColor(Qt::red); + + m_spawns.append(item); + } + + { + TankItem *item = new TankItem(this); + + item->setPos(m_scene->sceneRect().topRight() + QPointF(-30.0, 30.0)); + item->setDirection(135.0); + item->setColor(Qt::green); + + m_spawns.append(item); + } + + { + TankItem *item = new TankItem(this); + + item->setPos(m_scene->sceneRect().bottomRight() + QPointF(-30.0, -30.0)); + item->setDirection(225.0); + item->setColor(Qt::blue); + + m_spawns.append(item); + } + + { + TankItem *item = new TankItem(this); + + item->setPos(m_scene->sceneRect().bottomLeft() + QPointF(30.0, -30.0)); + item->setDirection(315.0); + item->setColor(Qt::yellow); + + m_spawns.append(item); + } + + QPointF centerOfMap = sceneRect.center(); + + addWall(QRectF(centerOfMap + QPointF(-50.0, -60.0), centerOfMap + QPointF(50.0, -50.0))); + addWall(QRectF(centerOfMap - QPointF(-50.0, -60.0), centerOfMap - QPointF(50.0, -50.0))); + addWall(QRectF(centerOfMap + QPointF(-50.0, -50.0), centerOfMap + QPointF(-40.0, 50.0))); + addWall(QRectF(centerOfMap - QPointF(-50.0, -50.0), centerOfMap - QPointF(-40.0, 50.0))); + + addWall(QRectF(sceneRect.topLeft() + QPointF(sceneRect.width() / 2.0 - 5.0, -10.0), + sceneRect.topLeft() + QPointF(sceneRect.width() / 2.0 + 5.0, 100.0))); + addWall(QRectF(sceneRect.bottomLeft() + QPointF(sceneRect.width() / 2.0 - 5.0, 10.0), + sceneRect.bottomLeft() + QPointF(sceneRect.width() / 2.0 + 5.0, -100.0))); + addWall(QRectF(sceneRect.topLeft() + QPointF(-10.0, sceneRect.height() / 2.0 - 5.0), + sceneRect.topLeft() + QPointF(100.0, sceneRect.height() / 2.0 + 5.0))); + addWall(QRectF(sceneRect.topRight() + QPointF(10.0, sceneRect.height() / 2.0 - 5.0), + sceneRect.topRight() + QPointF(-100.0, sceneRect.height() / 2.0 + 5.0))); + + + QAction *addTankAction = menuBar()->addAction("&Add tank"); + QAction *runGameAction = menuBar()->addAction("&Run game"); + runGameAction->setObjectName("runGameAction"); + QAction *stopGameAction = menuBar()->addAction("&Stop game"); + menuBar()->addSeparator(); + QAction *quitAction = menuBar()->addAction("&Quit"); + + connect(addTankAction, SIGNAL(triggered()), this, SLOT(addTank())); + connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); + + m_machine = new QStateMachine(this); + QState *stoppedState = new QState(m_machine->rootState()); + stoppedState->setObjectName("stoppedState"); + stoppedState->assignProperty(runGameAction, "enabled", true); + stoppedState->assignProperty(stopGameAction, "enabled", false); + stoppedState->assignProperty(this, "started", false); + m_machine->setInitialState(stoppedState); + +//! [5] + QState *spawnsAvailable = new QState(stoppedState); + spawnsAvailable->assignProperty(addTankAction, "enabled", true); + + QState *noSpawnsAvailable = new QState(stoppedState); + noSpawnsAvailable->assignProperty(addTankAction, "enabled", false); +//! [5] + spawnsAvailable->setObjectName("spawnsAvailable"); + noSpawnsAvailable->setObjectName("noSpawnsAvailable"); + + spawnsAvailable->addTransition(this, SIGNAL(mapFull()), noSpawnsAvailable); + +//! [3] + QHistoryState *hs = new QHistoryState(stoppedState); + hs->setDefaultState(spawnsAvailable); +//! [3] + hs->setObjectName("hs"); + + stoppedState->setInitialState(hs); + +//! [0] + m_runningState = new QState(QState::ParallelStates, m_machine->rootState()); +//! [0] + m_runningState->setObjectName("runningState"); + m_runningState->assignProperty(addTankAction, "enabled", false); + m_runningState->assignProperty(runGameAction, "enabled", false); + m_runningState->assignProperty(stopGameAction, "enabled", true); + + QState *gameOverState = new QState(m_machine->rootState()); + gameOverState->setObjectName("gameOverState"); + gameOverState->assignProperty(stopGameAction, "enabled", false); + connect(gameOverState, SIGNAL(entered()), this, SLOT(gameOver())); + + stoppedState->addTransition(runGameAction, SIGNAL(triggered()), m_runningState); + m_runningState->addTransition(stopGameAction, SIGNAL(triggered()), stoppedState); + + m_gameOverTransition = new GameOverTransition(gameOverState); + m_runningState->addTransition(m_gameOverTransition); + + QTimer *timer = new QTimer(this); + timer->setInterval(100); + connect(timer, SIGNAL(timeout()), this, SLOT(runStep())); + connect(m_runningState, SIGNAL(entered()), timer, SLOT(start())); + connect(m_runningState, SIGNAL(exited()), timer, SLOT(stop())); + + m_machine->start(); + m_time.start(); +} + +void MainWindow::runStep() +{ + if (!m_started) { + m_time.restart(); + m_started = true; + } else { + int elapsed = m_time.elapsed(); + if (elapsed > 0) { + m_time.restart(); + qreal elapsedSecs = elapsed / 1000.0; + QList items = m_scene->items(); + foreach (QGraphicsItem *item, items) { + if (GameItem *gameItem = qgraphicsitem_cast(item)) + gameItem->idle(elapsedSecs); + } + } + } +} + +void MainWindow::gameOver() +{ + QList items = m_scene->items(); + + TankItem *lastTankStanding = 0; + foreach (QGraphicsItem *item, items) { + if (GameItem *gameItem = qgraphicsitem_cast(item)) { + if ((lastTankStanding = qobject_cast(gameItem)) != 0) + break; + } + } + + QMessageBox::information(this, "Game over!", + QString::fromLatin1("The tank played by '%1' has won!").arg(lastTankStanding->objectName())); +} + +void MainWindow::addRocket() +{ + TankItem *tankItem = qobject_cast(sender()); + if (tankItem != 0) { + RocketItem *rocketItem = new RocketItem; + + QPointF s = tankItem->mapToScene(QPointF(tankItem->boundingRect().right() + 10.0, + tankItem->boundingRect().center().y())); + rocketItem->setPos(s); + rocketItem->setDirection(tankItem->direction()); + m_scene->addItem(rocketItem); + } +} + +void MainWindow::addTank() +{ + Q_ASSERT(!m_spawns.isEmpty()); + + QDir pluginsDir(qApp->applicationDirPath()); +#if defined(Q_OS_WIN) + if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release") + pluginsDir.cdUp(); +#elif defined(Q_OS_MAC) + if (pluginsDir.dirName() == "MacOS") { + pluginsDir.cdUp(); + pluginsDir.cdUp(); + pluginsDir.cdUp(); + } +#endif + + pluginsDir.cd("plugins"); + + QStringList itemNames; + QList items; + foreach (QString fileName, pluginsDir.entryList(QDir::Files)) { + QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); + QObject *possiblePlugin = loader.instance(); + if (Plugin *plugin = qobject_cast(possiblePlugin)) { + QString objectName = possiblePlugin->objectName(); + if (objectName.isEmpty()) + objectName = fileName; + + itemNames.append(objectName); + items.append(plugin); + } + } + + if (items.isEmpty()) { + QMessageBox::information(this, "No tank types found", "Please build the errorstateplugins directory"); + return; + } + + bool ok; +//! [1] + QString selectedName = QInputDialog::getItem(this, "Select a tank type", "Tank types", + itemNames, 0, false, &ok); +//! [1] + + if (ok && !selectedName.isEmpty()) { + int idx = itemNames.indexOf(selectedName); + if (Plugin *plugin = idx >= 0 ? items.at(idx) : 0) { + TankItem *tankItem = m_spawns.takeLast(); + tankItem->setObjectName(selectedName); + tankItem->setToolTip(selectedName); + m_scene->addItem(tankItem); + connect(tankItem, SIGNAL(cannonFired()), this, SLOT(addRocket())); + if (m_spawns.isEmpty()) + emit mapFull(); + + m_gameOverTransition->addTankItem(tankItem); + + QState *region = new QState(m_runningState); + region->setObjectName(QString::fromLatin1("region%1").arg(m_spawns.size())); +//! [2] + QState *pluginState = plugin->create(region, tankItem); +//! [2] + region->setInitialState(pluginState); + + // If the plugin has an error it is disabled +//! [4] + QState *errorState = new QState(region); + errorState->setObjectName(QString::fromLatin1("errorState%1").arg(m_spawns.size())); + errorState->assignProperty(tankItem, "enabled", false); + pluginState->setErrorState(errorState); +//! [4] + } + } +} + diff --git a/examples/statemachine/tankgame/mainwindow.h b/examples/statemachine/tankgame/mainwindow.h new file mode 100644 index 0000000..4ae8f7a --- /dev/null +++ b/examples/statemachine/tankgame/mainwindow.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QGraphicsScene; +class QStateMachine; +class QState; +QT_END_NAMESPACE +class GameOverTransition; +class TankItem; + +class MainWindow: public QMainWindow +{ + Q_OBJECT + Q_PROPERTY(bool started READ started WRITE setStarted) +public: + MainWindow(QWidget *parent = 0); + ~MainWindow(); + + void setStarted(bool b) { m_started = b; } + bool started() const { return m_started; } + +public slots: + void addTank(); + void addRocket(); + void runStep(); + void gameOver(); + +signals: + void mapFull(); + +private: + void init(); + void addWall(const QRectF &wall); + + QGraphicsScene *m_scene; + + QStateMachine *m_machine; + QState *m_runningState; + GameOverTransition *m_gameOverTransition; + + QList m_spawns; + QTime m_time; + + bool m_started : 1; +}; + +#endif + diff --git a/examples/statemachine/tankgame/plugin.h b/examples/statemachine/tankgame/plugin.h new file mode 100644 index 0000000..ddd10b7 --- /dev/null +++ b/examples/statemachine/tankgame/plugin.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PLUGIN_H +#define PLUGIN_H + +#include + +QT_BEGIN_NAMESPACE +class QState; +QT_END_NAMESPACE +class Plugin +{ +public: + virtual ~Plugin() {} + + virtual QState *create(QState *parentState, QObject *tank) = 0; +}; + +QT_BEGIN_NAMESPACE +Q_DECLARE_INTERFACE(Plugin, "TankPlugin") +QT_END_NAMESPACE + +#endif diff --git a/examples/statemachine/tankgame/rocketitem.cpp b/examples/statemachine/tankgame/rocketitem.cpp new file mode 100644 index 0000000..3ace8e8 --- /dev/null +++ b/examples/statemachine/tankgame/rocketitem.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "rocketitem.h" +#include "tankitem.h" + +#include +#include + +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +RocketItem::RocketItem(QObject *parent) + : GameItem(parent), m_direction(0.0), m_distance(300.0) +{ +} + +QRectF RocketItem::boundingRect() const +{ + return QRectF(-1.0, -1.0, 2.0, 2.0); +} + +void RocketItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + painter->setBrush(Qt::black); + painter->drawEllipse(boundingRect()); +} + +void RocketItem::idle(qreal elapsed) +{ + qreal dist = elapsed * speed(); + + m_distance -= dist; + if (m_distance < 0.0) { + scene()->removeItem(this); + delete this; + return; + } + + qreal a = m_direction * M_PI / 180.0; + + qreal yd = dist * sin(a); + qreal xd = dist * sin(M_PI / 2.0 - a); + + QPointF requestedPosition = pos() + QPointF(xd, yd); + QGraphicsItem *collidedItem = 0; + QPointF nextPosition = tryMove(requestedPosition, 0, &collidedItem); + if (requestedPosition == nextPosition) { + setPos(nextPosition); + } else { + if (GameItem *gameItem = qgraphicsitem_cast(collidedItem)) { + TankItem *tankItem = qobject_cast(gameItem); + if (tankItem != 0) + tankItem->hitByRocket(); + } + + scene()->removeItem(this); + delete this; + } +} diff --git a/examples/statemachine/tankgame/rocketitem.h b/examples/statemachine/tankgame/rocketitem.h new file mode 100644 index 0000000..31146a6 --- /dev/null +++ b/examples/statemachine/tankgame/rocketitem.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ROCKETITEM_H +#define ROCKETITEM_H + +#include "gameitem.h" + +class RocketItem: public GameItem +{ + Q_OBJECT +public: + RocketItem(QObject *parent = 0); + + virtual void idle(qreal elapsed); + qreal speed() const { return 100.0; } + void setDirection(qreal direction) { m_direction = direction; } + +protected: + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + QRectF boundingRect() const; + +private: + qreal m_direction; + qreal m_distance; +}; + +#endif diff --git a/examples/statemachine/tankgame/tankgame.pro b/examples/statemachine/tankgame/tankgame.pro new file mode 100644 index 0000000..59415be --- /dev/null +++ b/examples/statemachine/tankgame/tankgame.pro @@ -0,0 +1,19 @@ +HEADERS += mainwindow.h \ + plugin.h \ + tankitem.h \ + rocketitem.h \ + gameitem.h \ + gameovertransition.h +SOURCES += main.cpp \ + mainwindow.cpp \ + tankitem.cpp \ + rocketitem.cpp \ + gameitem.cpp \ + gameovertransition.cpp +CONFIG += console + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS tankgame.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame +INSTALLS += target sources diff --git a/examples/statemachine/tankgame/tankitem.cpp b/examples/statemachine/tankgame/tankitem.cpp new file mode 100644 index 0000000..393d65f --- /dev/null +++ b/examples/statemachine/tankgame/tankitem.cpp @@ -0,0 +1,302 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "tankitem.h" + +#include +#include +#include + +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +class Action +{ +public: + Action(TankItem *item) : m_item(item) + { + } + + TankItem *item() const { return m_item; } + void setItem(TankItem *item) { m_item = item; } + + virtual bool apply(qreal timeDelta) = 0; + +private: + TankItem *m_item; +}; + +class MoveAction: public Action +{ +public: + MoveAction(TankItem *item, qreal distance) + : Action(item), m_distance(distance) + { + m_reverse = m_distance < 0.0; + } + + bool apply(qreal timeDelta) + { + qreal dist = timeDelta * item()->speed() * (m_reverse ? -1.0 : 1.0); + + bool done = false; + if (qAbs(m_distance) < qAbs(dist)) { + done = true; + dist = m_distance; + } + m_distance -= dist; + + qreal a = item()->direction() * M_PI / 180.0; + + qreal yd = dist * sin(a); + qreal xd = dist * sin(M_PI / 2.0 - a); + + item()->setPos(item()->pos() + QPointF(xd, yd)); + return !done; + } + +private: + qreal m_distance; + bool m_reverse; +}; + +class TurnAction: public Action +{ +public: + TurnAction(TankItem *item, qreal distance) + : Action(item), m_distance(distance) + { + m_reverse = m_distance < 0.0; + } + + bool apply(qreal timeDelta) + { + qreal dist = timeDelta * item()->angularSpeed() * (m_reverse ? -1.0 : 1.0); + bool done = false; + if (qAbs(m_distance) < qAbs(dist)) { + done = true; + dist = m_distance; + } + m_distance -= dist; + + item()->setDirection(item()->direction() + dist); + return !done; + } + +private: + qreal m_distance; + bool m_reverse; +}; + +TankItem::TankItem(QObject *parent) + : GameItem(parent), m_currentAction(0), m_currentDirection(0.0), m_enabled(true) +{ + connect(this, SIGNAL(cannonFired()), this, SIGNAL(actionCompleted())); +} + +void TankItem::idle(qreal elapsed) +{ + if (m_enabled) { + if (m_currentAction != 0) { + if (!m_currentAction->apply(elapsed)) { + setAction(0); + emit actionCompleted(); + } + + QGraphicsItem *item = 0; + qreal distance = distanceToObstacle(&item); + if (TankItem *tankItem = qgraphicsitem_cast(item)) + emit tankSpotted(tankItem->direction(), distance); + } + } +} + +void TankItem::hitByRocket() +{ + emit aboutToBeDestroyed(); + deleteLater(); +} + +void TankItem::setAction(Action *newAction) +{ + if (m_currentAction != 0) + delete m_currentAction; + + m_currentAction = newAction; +} + +void TankItem::fireCannon() +{ + emit cannonFired(); +} + +void TankItem::moveForwards(qreal length) +{ + setAction(new MoveAction(this, length)); +} + +void TankItem::moveBackwards(qreal length) +{ + setAction(new MoveAction(this, -length)); +} + +void TankItem::turn(qreal degrees) +{ + setAction(new TurnAction(this, degrees)); +} + +void TankItem::turnTo(qreal degrees) +{ + setAction(new TurnAction(this, degrees - direction())); +} + +void TankItem::stop() +{ + setAction(0); +} + +QVariant TankItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemPositionChange && scene()) { + QPointF requestedPosition = value.toPointF(); + QLineF collidedLine; + QPointF nextPoint = tryMove(requestedPosition, &collidedLine); + if (nextPoint != requestedPosition) + emit collision(collidedLine); + return nextPoint; + } else { + return QGraphicsItem::itemChange(change, value); + } +} + + +void TankItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + QRectF brect = boundingRect(); + + painter->setBrush(m_color); + painter->setPen(Qt::black); + + // body + painter->drawRect(brect.adjusted(0.0, 4.0, -2.0, -4.0)); + + // cannon + QRectF cannonBase = brect.adjusted(10.0, 6.0, -12.0, -6.0); + painter->drawEllipse(cannonBase); + + painter->drawRect(QRectF(QPointF(cannonBase.center().x(), cannonBase.center().y() - 2.0), + QPointF(brect.right(), cannonBase.center().y() + 2.0))); + + // left track + painter->setBrush(QBrush(Qt::black, Qt::VerPattern)); + QRectF leftTrackRect = QRectF(brect.topLeft(), QPointF(brect.right() - 2.0, brect.top() + 4.0)); + painter->fillRect(leftTrackRect, Qt::darkYellow); + painter->drawRect(leftTrackRect); + + // right track + QRectF rightTrackRect = QRectF(QPointF(brect.left(), brect.bottom() - 4.0), + QPointF(brect.right() - 2.0, brect.bottom())); + painter->fillRect(rightTrackRect, Qt::darkYellow); + painter->drawRect(rightTrackRect); + + if (!m_enabled) { + painter->setPen(QPen(Qt::red, 5)); + + painter->drawEllipse(brect); + + QPainterPath path; + path.addEllipse(brect); + painter->setClipPath(path); + painter->drawLine(brect.topRight(), brect.bottomLeft()); + } +} + +QRectF TankItem::boundingRect() const +{ + return QRectF(-20.0, -10.0, 40.0, 20.0); +} + +qreal TankItem::direction() const +{ + return m_currentDirection; +} + +void TankItem::setDirection(qreal newDirection) +{ + int fullRotations = int(newDirection) / 360; + newDirection -= fullRotations * 360.0; + + qreal diff = newDirection - m_currentDirection; + m_currentDirection = newDirection; + rotate(diff); +} + +qreal TankItem::distanceToObstacle(QGraphicsItem **obstacle) const +{ + qreal dist = sqrt(pow(scene()->sceneRect().width(), 2) + pow(scene()->sceneRect().height(), 2)); + + qreal a = m_currentDirection * M_PI / 180.0; + + qreal yd = dist * sin(a); + qreal xd = dist * sin(M_PI / 2.0 - a); + + QPointF requestedPosition = pos() + QPointF(xd, yd); + QGraphicsItem *collidedItem = 0; + QPointF nextPosition = tryMove(requestedPosition, 0, &collidedItem); + if (collidedItem != 0) { + if (obstacle != 0) + *obstacle = collidedItem; + + QPointF d = nextPosition - pos(); + return sqrt(pow(d.x(), 2) + pow(d.y(), 2)); + } else { + return 0.0; + } +} + +qreal TankItem::distanceToObstacle() const +{ + return distanceToObstacle(0); +} + diff --git a/examples/statemachine/tankgame/tankitem.h b/examples/statemachine/tankgame/tankitem.h new file mode 100644 index 0000000..942fca8 --- /dev/null +++ b/examples/statemachine/tankgame/tankitem.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TANKITEM_H +#define TANKITEM_H + +#include "gameitem.h" + +#include + +class Action; +class TankItem: public GameItem +{ + Q_OBJECT + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled) + Q_PROPERTY(qreal direction READ direction WRITE turnTo) + Q_PROPERTY(qreal distanceToObstacle READ distanceToObstacle) +public: + TankItem(QObject *parent = 0); + + void setColor(const QColor &color) { m_color = color; } + QColor color() const { return m_color; } + + void idle(qreal elapsed); + void setDirection(qreal newDirection); + + qreal speed() const { return 90.0; } + qreal angularSpeed() const { return 90.0; } + + QRectF boundingRect() const; + + void hitByRocket(); + + void setEnabled(bool b) { m_enabled = b; } + bool enabled() const { return m_enabled; } + + qreal direction() const; + qreal distanceToObstacle() const; + qreal distanceToObstacle(QGraphicsItem **item) const; + +//! [0] +signals: + void tankSpotted(qreal direction, qreal distance); + void collision(const QLineF &collidedLine); + void actionCompleted(); + void cannonFired(); + void aboutToBeDestroyed(); + +public slots: + void moveForwards(qreal length = 10.0); + void moveBackwards(qreal length = 10.0); + void turn(qreal degrees = 30.0); + void turnTo(qreal degrees = 0.0); + void stop(); + void fireCannon(); +//! [0] + +protected: + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value); + +private: + void setAction(Action *newAction); + + Action *m_currentAction; + qreal m_currentDirection; + QColor m_color; + bool m_enabled; +}; + +#endif diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai.pro b/examples/statemachine/tankgameplugins/random_ai/random_ai.pro new file mode 100644 index 0000000..5bc0b26 --- /dev/null +++ b/examples/statemachine/tankgameplugins/random_ai/random_ai.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += plugin +INCLUDEPATH += ../.. +HEADERS = random_ai_plugin.h +SOURCES = random_ai_plugin.cpp +TARGET = $$qtLibraryTarget(random_ai) +DESTDIR = ../../tankgame/plugins + +#! [0] +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS random_ai.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/random_ai \ No newline at end of file diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp new file mode 100644 index 0000000..d360de9 --- /dev/null +++ b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "random_ai_plugin.h" + +#include +#include + +#include + +QState *RandomAiPlugin::create(QState *parentState, QObject *tank) +{ + qsrand(uint(time(NULL))); + + QState *topLevel = new QState(parentState); + + QState *selectNextActionState = new SelectActionState(topLevel); + topLevel->setInitialState(selectNextActionState); + + QState *fireState = new RandomDistanceState(topLevel); + connect(fireState, SIGNAL(distanceComputed(qreal)), tank, SLOT(fireCannon())); + selectNextActionState->addTransition(selectNextActionState, SIGNAL(fireSelected()), fireState); + + QState *moveForwardsState = new RandomDistanceState(topLevel); + connect(moveForwardsState, SIGNAL(distanceComputed(qreal)), tank, SLOT(moveForwards(qreal))); + selectNextActionState->addTransition(selectNextActionState, SIGNAL(moveForwardsSelected()), moveForwardsState); + + QState *moveBackwardsState = new RandomDistanceState(topLevel); + connect(moveBackwardsState, SIGNAL(distanceComputed(qreal)), tank, SLOT(moveBackwards(qreal))); + selectNextActionState->addTransition(selectNextActionState, SIGNAL(moveBackwardsSelected()), moveBackwardsState); + + QState *turnState = new RandomDistanceState(topLevel); + connect(turnState, SIGNAL(distanceComputed(qreal)), tank, SLOT(turn(qreal))); + selectNextActionState->addTransition(selectNextActionState, SIGNAL(turnSelected()), turnState); + + topLevel->addTransition(tank, SIGNAL(actionCompleted()), selectNextActionState); + + return topLevel; +} + +Q_EXPORT_PLUGIN2(random_ai, RandomAiPlugin) diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h new file mode 100644 index 0000000..9faeeac --- /dev/null +++ b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RANDOM_AI_PLUGIN_H +#define RANDOM_AI_PLUGIN_H + +#include +#include + +#include + +class SelectActionState: public QState +{ + Q_OBJECT +public: + SelectActionState(QState *parent = 0) : QState(parent) + { + } + +signals: + void fireSelected(); + void moveForwardsSelected(); + void moveBackwardsSelected(); + void turnSelected(); + +protected: + void onEntry(QEvent *) + { + int rand = qrand() % 4; + switch (rand) { + case 0: emit fireSelected(); break; + case 1: emit moveForwardsSelected(); break; + case 2: emit moveBackwardsSelected(); break; + case 3: emit turnSelected(); break; + }; + } +}; + +class RandomDistanceState: public QState +{ + Q_OBJECT +public: + RandomDistanceState(QState *parent = 0) : QState(parent) + { + } + +signals: + void distanceComputed(qreal distance); + +protected: + void onEntry(QEvent *) + { + emit distanceComputed(qreal(qrand() % 180)); + } +}; + +class RandomAiPlugin: public QObject, public Plugin +{ + Q_OBJECT + Q_INTERFACES(Plugin) +public: + RandomAiPlugin() { setObjectName("Random"); } + + virtual QState *create(QState *parentState, QObject *tank); +}; + +#endif // RANDOM_AI_PLUGIN_H diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp new file mode 100644 index 0000000..6aae015 --- /dev/null +++ b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "seek_ai.h" + +QState *SeekAi::create(QState *parentState, QObject *tank) +{ + QState *topLevel = new QState(parentState); + topLevel->setObjectName("topLevel"); + + QState *seek = new QState(topLevel); + seek->setObjectName("seek"); + topLevel->setInitialState(seek); + + QState *lookForNearestWall = new SearchState(tank, seek); + lookForNearestWall->setObjectName("lookForNearestWall"); + seek->setInitialState(lookForNearestWall); + + QState *driveToFirstObstacle = new QState(seek); + driveToFirstObstacle->setObjectName("driveToFirstObstacle"); + lookForNearestWall->addTransition(lookForNearestWall, SIGNAL(nearestObstacleStraightAhead()), + driveToFirstObstacle); + + QState *drive = new QState(driveToFirstObstacle); + drive->setObjectName("drive"); + driveToFirstObstacle->setInitialState(drive); + connect(drive, SIGNAL(entered()), tank, SLOT(moveForwards())); + connect(drive, SIGNAL(exited()), tank, SLOT(stop())); + + // Go in loop + QState *finishedDriving = new QState(driveToFirstObstacle); + finishedDriving->setObjectName("finishedDriving"); + drive->addTransition(tank, SIGNAL(actionCompleted()), finishedDriving); + finishedDriving->addTransition(drive); + + QState *turnTo = new QState(seek); + turnTo->setObjectName("turnTo"); + driveToFirstObstacle->addTransition(new CollisionTransition(tank, turnTo)); + + turnTo->addTransition(tank, SIGNAL(actionCompleted()), driveToFirstObstacle); + + ChaseState *chase = new ChaseState(tank, topLevel); + chase->setObjectName("chase"); + seek->addTransition(new TankSpottedTransition(tank, chase)); + chase->addTransition(chase, SIGNAL(finished()), driveToFirstObstacle); + chase->addTransition(new TankSpottedTransition(tank, chase)); + + return topLevel; +} + +Q_EXPORT_PLUGIN2(seek_ai, SeekAi) diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h new file mode 100644 index 0000000..e44ad07 --- /dev/null +++ b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SEEK_AI_H +#define SEEK_AI_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +class SearchState: public QState +{ + Q_OBJECT +public: + SearchState(QObject *tank, QState *parentState = 0) + : QState(parentState), + m_tank(tank), + m_distanceToTurn(360.0), + m_nearestDistance(-1.0), + m_directionOfNearestObstacle(0.0) + { + } + +public slots: + void turnAlittle() + { + qreal dist = m_tank->property("distanceToObstacle").toDouble(); + + if (m_nearestDistance < 0.0 || dist < m_nearestDistance) { + m_nearestDistance = dist; + m_directionOfNearestObstacle = m_tank->property("direction").toDouble(); + } + + m_distanceToTurn -= 10.0; + if (m_distanceToTurn < 0.0) { + disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(turnAlittle())); + connect(m_tank, SIGNAL(actionCompleted()), this, SIGNAL(nearestObstacleStraightAhead())); + m_tank->setProperty("direction", m_directionOfNearestObstacle); + } + + qreal currentDirection = m_tank->property("direction").toDouble(); + m_tank->setProperty("direction", currentDirection + 10.0); + } + +signals: + void nearestObstacleStraightAhead(); + +protected: + void onEntry(QEvent *) + { + connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(turnAlittle())); + turnAlittle(); + } + + void onExit(QEvent *) + { + disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(turnAlittle())); + disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(nearestObstacleStraightAhead())); + } + +private: + QObject *m_tank; + + qreal m_distanceToTurn; + qreal m_nearestDistance; + qreal m_directionOfNearestObstacle; +}; + +class CollisionTransition: public QSignalTransition +{ +public: + CollisionTransition(QObject *tank, QState *turnTo) + : QSignalTransition(tank, SIGNAL(collision(QLineF))), + m_tank(tank), + m_turnTo(turnTo) + { + setTargetState(turnTo); + } + +protected: + bool eventTest(QEvent *event) + { + bool b = QSignalTransition::eventTest(event); + if (b) { + QSignalEvent *se = static_cast(event); + m_lastLine = se->arguments().at(0).toLineF(); + } + return b; + } + + void onTransition(QEvent *) + { + qreal angleOfWall = m_lastLine.angle(); + + qreal newDirection; + if (qrand() % 2 == 0) + newDirection = angleOfWall; + else + newDirection = angleOfWall - 180.0; + + m_turnTo->assignProperty(m_tank, "direction", newDirection); + } + +private: + QLineF m_lastLine; + QObject *m_tank; + QState *m_turnTo; +}; + +class ChaseState: public QState +{ + class GoToLocationState: public QState + { + public: + GoToLocationState(QObject *tank, QState *parentState = 0) + : QState(parentState), m_tank(tank), m_distance(0.0) + { + } + + void setDistance(qreal distance) { m_distance = distance; } + + protected: + void onEntry() + { + QMetaObject::invokeMethod(m_tank, "moveForwards", Q_ARG(qreal, m_distance)); + } + + private: + QObject *m_tank; + qreal m_distance; + }; + +public: + ChaseState(QObject *tank, QState *parentState = 0) : QState(parentState), m_tank(tank) + { + QState *fireCannon = new QState(this); + fireCannon->setObjectName("fireCannon"); + connect(fireCannon, SIGNAL(entered()), tank, SLOT(fireCannon())); + setInitialState(fireCannon); + + m_goToLocation = new GoToLocationState(tank, this); + m_goToLocation->setObjectName("goToLocation"); + fireCannon->addTransition(tank, SIGNAL(actionCompleted()), m_goToLocation); + + m_turnToDirection = new QState(this); + m_turnToDirection->setObjectName("turnToDirection"); + m_goToLocation->addTransition(tank, SIGNAL(actionCompleted()), m_turnToDirection); + + QFinalState *finalState = new QFinalState(this); + finalState->setObjectName("finalState"); + m_turnToDirection->addTransition(tank, SIGNAL(actionCompleted()), finalState); + } + + void setDirection(qreal direction) + { + m_turnToDirection->assignProperty(m_tank, "direction", direction); + } + + void setDistance(qreal distance) + { + m_goToLocation->setDistance(distance); + } + +private: + QObject *m_tank; + GoToLocationState *m_goToLocation; + QState *m_turnToDirection; + +}; + +class TankSpottedTransition: public QSignalTransition +{ +public: + TankSpottedTransition(QObject *tank, ChaseState *target) : QSignalTransition(tank, SIGNAL(tankSpotted(qreal,qreal))), m_chase(target) + { + setTargetState(target); + } + +protected: + bool eventTest(QEvent *event) + { + bool b = QSignalTransition::eventTest(event); + if (b) { + QSignalEvent *se = static_cast(event); + m_chase->setDirection(se->arguments().at(0).toDouble()); + m_chase->setDistance(se->arguments().at(1).toDouble()); + } + return b; + } + +private: + ChaseState *m_chase; +}; + +class SeekAi: public QObject, public Plugin +{ + Q_OBJECT + Q_INTERFACES(Plugin) +public: + SeekAi() { setObjectName("Seek and destroy"); } + + virtual QState *create(QState *parentState, QObject *tank); +}; + +#endif diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro new file mode 100644 index 0000000..0d8bf2e --- /dev/null +++ b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += plugin +INCLUDEPATH += ../.. +HEADERS = seek_ai.h +SOURCES = seek_ai.cpp +TARGET = $$qtLibraryTarget(seek_ai) +DESTDIR = ../../tankgame/plugins + +#! [0] +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS seek_ai.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/seek_ai \ No newline at end of file diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp new file mode 100644 index 0000000..581a6b2 --- /dev/null +++ b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "spin_ai.h" + +#include + +QState *SpinAi::create(QState *parentState, QObject *tank) +{ + QState *topLevel = new QState(parentState); + QState *spinState = new SpinState(tank, topLevel); + topLevel->setInitialState(spinState); + + // When tank is spotted, fire two times and go back to spin state + QState *fireState = new QState(topLevel); + + QState *fireOnce = new QState(fireState); + fireState->setInitialState(fireOnce); + connect(fireOnce, SIGNAL(entered()), tank, SLOT(fireCannon())); + + QState *fireTwice = new QState(fireState); + connect(fireTwice, SIGNAL(entered()), tank, SLOT(fireCannon())); + + fireOnce->addTransition(tank, SIGNAL(actionCompleted()), fireTwice); + fireTwice->addTransition(tank, SIGNAL(actionCompleted()), spinState); + + spinState->addTransition(tank, SIGNAL(tankSpotted(qreal,qreal)), fireState); + + return topLevel; +} + +Q_EXPORT_PLUGIN2(spin_ai, SpinAi) diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h new file mode 100644 index 0000000..652e8b8 --- /dev/null +++ b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SPIN_AI_H +#define SPIN_AI_H + +#include + +#include +#include +#include + +class SpinState: public QState +{ + Q_OBJECT +public: + SpinState(QObject *tank, QState *parent) : QState(parent), m_tank(tank) + { + } + +public slots: + void spin() + { + m_tank->setProperty("direction", m_tank->property("direction").toDouble() + 90.0); + } + +protected: + void onEntry(QEvent *) + { + connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); + spin(); + } + + void onExit(QEvent *) + { + disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); + } + +private: + QObject *m_tank; + +}; + +class SpinAi: public QObject, public Plugin +{ + Q_OBJECT + Q_INTERFACES(Plugin) +public: + SpinAi() { setObjectName("Spin and destroy"); } + + virtual QState *create(QState *parentState, QObject *tank); +}; + +#endif diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro new file mode 100644 index 0000000..8ab4da0 --- /dev/null +++ b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += plugin +INCLUDEPATH += ../.. +HEADERS = spin_ai.h +SOURCES = spin_ai.cpp +TARGET = $$qtLibraryTarget(spin_ai) +DESTDIR = ../../tankgame/plugins + +#! [0] +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS spin_ai.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/spin_ai \ No newline at end of file diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp new file mode 100644 index 0000000..19137b2 --- /dev/null +++ b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "spin_ai_with_error.h" + +#include + +QState *SpinAiWithError::create(QState *parentState, QObject *tank) +{ + QState *topLevel = new QState(parentState); + QState *spinState = new SpinState(tank, topLevel); + topLevel->setInitialState(spinState); + + // When tank is spotted, fire two times and go back to spin state + // (no initial state set for fireState will lead to run-time error in machine) + QState *fireState = new QState(topLevel); + + QState *fireOnce = new QState(fireState); + connect(fireOnce, SIGNAL(entered()), tank, SLOT(fireCannon())); + + QState *fireTwice = new QState(fireState); + connect(fireTwice, SIGNAL(entered()), tank, SLOT(fireCannon())); + + fireOnce->addTransition(tank, SIGNAL(actionCompleted()), fireTwice); + fireTwice->addTransition(tank, SIGNAL(actionCompleted()), spinState); + + spinState->addTransition(tank, SIGNAL(tankSpotted(qreal,qreal)), fireState); + + return topLevel; +} + +Q_EXPORT_PLUGIN2(spin_ai_with_error, SpinAiWithError) diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h new file mode 100644 index 0000000..e040bf2 --- /dev/null +++ b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SPIN_AI_WITH_ERROR_H +#define SPIN_AI_WITH_ERROR_H + +#include + +#include +#include +#include + +class SpinState: public QState +{ + Q_OBJECT +public: + SpinState(QObject *tank, QState *parent) : QState(parent), m_tank(tank) + { + } + +public slots: + void spin() + { + m_tank->setProperty("direction", m_tank->property("direction").toDouble() + 90.0); + } + +protected: + void onEntry(QEvent *) + { + connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); + spin(); + } + + void onExit(QEvent *) + { + disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); + } + +private: + QObject *m_tank; + +}; + +class SpinAiWithError: public QObject, public Plugin +{ + Q_OBJECT + Q_INTERFACES(Plugin) +public: + SpinAiWithError() { setObjectName("Spin and destroy with runtime error in state machine"); } + + virtual QState *create(QState *parentState, QObject *tank); +}; + +#endif diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro new file mode 100644 index 0000000..124cf98 --- /dev/null +++ b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += plugin +INCLUDEPATH += ../.. +HEADERS = spin_ai_with_error.h +SOURCES = spin_ai_with_error.cpp +TARGET = $$qtLibraryTarget(spin_ai_with_error) +DESTDIR = ../../tankgame/plugins + +#! [0] +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS spin_ai_with_error.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/spin_ai_with_error \ No newline at end of file diff --git a/examples/statemachine/tankgameplugins/tankgameplugins.pro b/examples/statemachine/tankgameplugins/tankgameplugins.pro new file mode 100644 index 0000000..a098e03 --- /dev/null +++ b/examples/statemachine/tankgameplugins/tankgameplugins.pro @@ -0,0 +1,11 @@ +TEMPLATE = subdirs +SUBDIRS = random_ai \ + spin_ai_with_error \ + spin_ai \ + seek_ai + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS tankgameplugins.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins +INSTALLS += target sources diff --git a/examples/statemachine/trafficlight/main.cpp b/examples/statemachine/trafficlight/main.cpp new file mode 100644 index 0000000..8a46fff --- /dev/null +++ b/examples/statemachine/trafficlight/main.cpp @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#ifdef QT_STATEMACHINE_SOLUTION +#include +#include +#include +#endif + +//! [0] +class LightWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(bool on READ isOn WRITE setOn) +public: + LightWidget(const QColor &color, QWidget *parent = 0) + : QWidget(parent), m_color(color), m_on(false) {} + + bool isOn() const + { return m_on; } + void setOn(bool on) + { + if (on == m_on) + return; + m_on = on; + update(); + } + +public slots: + void turnOff() { setOn(false); } + void turnOn() { setOn(true); } + +protected: + virtual void paintEvent(QPaintEvent *) + { + if (!m_on) + return; + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setBrush(m_color); + painter.drawEllipse(0, 0, width(), height()); + } + +private: + QColor m_color; + bool m_on; +}; +//! [0] + +//! [1] +class TrafficLightWidget : public QWidget +{ +public: + TrafficLightWidget(QWidget *parent = 0) + : QWidget(parent) + { + QVBoxLayout *vbox = new QVBoxLayout(this); + m_red = new LightWidget(Qt::red); + vbox->addWidget(m_red); + m_yellow = new LightWidget(Qt::yellow); + vbox->addWidget(m_yellow); + m_green = new LightWidget(Qt::green); + vbox->addWidget(m_green); + QPalette pal = palette(); + pal.setColor(QPalette::Background, Qt::black); + setPalette(pal); + setAutoFillBackground(true); + } + + LightWidget *redLight() const + { return m_red; } + LightWidget *yellowLight() const + { return m_yellow; } + LightWidget *greenLight() const + { return m_green; } + +private: + LightWidget *m_red; + LightWidget *m_yellow; + LightWidget *m_green; +}; +//! [1] + +//! [2] +QState *createLightState(LightWidget *light, int duration, QState *parent = 0) +{ + QState *lightState = new QState(parent); + QTimer *timer = new QTimer(lightState); + timer->setInterval(duration); + timer->setSingleShot(true); + QState *timing = new QState(lightState); + QObject::connect(timing, SIGNAL(entered()), light, SLOT(turnOn())); + QObject::connect(timing, SIGNAL(entered()), timer, SLOT(start())); + QObject::connect(timing, SIGNAL(exited()), light, SLOT(turnOff())); + QFinalState *done = new QFinalState(lightState); + timing->addTransition(timer, SIGNAL(timeout()), done); + lightState->setInitialState(timing); + return lightState; +} +//! [2] + +//! [3] +class TrafficLight : public QWidget +{ +public: + TrafficLight(QWidget *parent = 0) + : QWidget(parent) + { + QVBoxLayout *vbox = new QVBoxLayout(this); + TrafficLightWidget *widget = new TrafficLightWidget(); + vbox->addWidget(widget); + vbox->setMargin(0); + + QStateMachine *machine = new QStateMachine(this); + QState *redGoingYellow = createLightState(widget->redLight(), 3000); + redGoingYellow->setObjectName("redGoingYellow"); + QState *yellowGoingGreen = createLightState(widget->yellowLight(), 1000); + yellowGoingGreen->setObjectName("yellowGoingGreen"); + redGoingYellow->addTransition(redGoingYellow, SIGNAL(finished()), yellowGoingGreen); + QState *greenGoingYellow = createLightState(widget->greenLight(), 3000); + greenGoingYellow->setObjectName("greenGoingYellow"); + yellowGoingGreen->addTransition(yellowGoingGreen, SIGNAL(finished()), greenGoingYellow); + QState *yellowGoingRed = createLightState(widget->yellowLight(), 1000); + yellowGoingRed->setObjectName("yellowGoingRed"); + greenGoingYellow->addTransition(greenGoingYellow, SIGNAL(finished()), yellowGoingRed); + yellowGoingRed->addTransition(yellowGoingRed, SIGNAL(finished()), redGoingYellow); + + machine->addState(redGoingYellow); + machine->addState(yellowGoingGreen); + machine->addState(greenGoingYellow); + machine->addState(yellowGoingRed); + machine->setInitialState(redGoingYellow); + machine->start(); + } +}; +//! [3] + +//! [4] +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + TrafficLight widget; + widget.resize(110, 300); + widget.show(); + + return app.exec(); +} +//! [4] + +#include "main.moc" diff --git a/examples/statemachine/trafficlight/trafficlight.pro b/examples/statemachine/trafficlight/trafficlight.pro new file mode 100644 index 0000000..684575a --- /dev/null +++ b/examples/statemachine/trafficlight/trafficlight.pro @@ -0,0 +1,7 @@ +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/trafficlight +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS trafficlight.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/trafficlight +INSTALLS += target sources diff --git a/examples/statemachine/twowaybutton/main.cpp b/examples/statemachine/twowaybutton/main.cpp new file mode 100644 index 0000000..a2c6e45 --- /dev/null +++ b/examples/statemachine/twowaybutton/main.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#ifdef QT_STATEMACHINE_SOLUTION +#include +#include +#endif + +//! [0] +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + QPushButton button; + QStateMachine machine; +//! [0] + +//! [1] + QState *off = new QState(); + off->assignProperty(&button, "text", "Off"); + off->setObjectName("off"); + + QState *on = new QState(); + on->setObjectName("on"); + on->assignProperty(&button, "text", "On"); +//! [1] + +//! [2] + off->addTransition(&button, SIGNAL(clicked()), on); + on->addTransition(&button, SIGNAL(clicked()), off); +//! [2] + +//! [3] + machine.addState(off); + machine.addState(on); +//! [3] + +//! [4] + machine.setInitialState(off); + machine.start(); +//! [4] + +//! [5] + button.resize(100, 50); + button.show(); + return app.exec(); +} +//! [5] diff --git a/examples/statemachine/twowaybutton/twowaybutton.pro b/examples/statemachine/twowaybutton/twowaybutton.pro new file mode 100644 index 0000000..f6cbc57 --- /dev/null +++ b/examples/statemachine/twowaybutton/twowaybutton.pro @@ -0,0 +1,7 @@ +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/twowaybutton +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS twowaybutton.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/twowaybutton +INSTALLS += target sources diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index 03582fc..78c947d 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -16,7 +16,7 @@ QMAKE_LEX = flex QMAKE_LEXFLAGS = QMAKE_YACC = byacc QMAKE_YACCFLAGS = -d -QMAKE_CFLAGS = -nologo -Zm200 /Qprec +QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738 QMAKE_CFLAGS_WARN_ON = -W3 /Qwd673 QMAKE_CFLAGS_WARN_OFF = -W0 /Qwd673 QMAKE_CFLAGS_RELEASE = -O2 -MD diff --git a/src/3rdparty/easing/easing.cpp b/src/3rdparty/easing/easing.cpp new file mode 100644 index 0000000..81af40f --- /dev/null +++ b/src/3rdparty/easing/easing.cpp @@ -0,0 +1,670 @@ +/* +Disclaimer for Robert Penner's Easing Equations license: + +TERMS OF USE - EASING EQUATIONS + +Open source under the BSD License. + +Copyright © 2001 Robert Penner +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#ifndef M_PI_2 +#define M_PI_2 (M_PI / 2) +#endif + +QT_USE_NAMESPACE + +/** + * Easing equation function for a simple linear tweening, with no easing. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeNone(qreal progress) +{ + return progress; +} + +/** + * Easing equation function for a quadratic (t^2) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInQuad(qreal t) +{ + return t*t; +} + +/** +* Easing equation function for a quadratic (t^2) easing out: decelerating to zero velocity. +* +* @param t Current time (in frames or seconds). +* @return The correct value. +*/ +static qreal easeOutQuad(qreal t) +{ + return -t*(t-2); +} + +/** + * Easing equation function for a quadratic (t^2) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInOutQuad(qreal t) +{ + t*=2.0; + if (t < 1) { + return t*t/qreal(2); + } else { + --t; + return -0.5 * (t*(t-2) - 1); + } +} + +/** + * Easing equation function for a quadratic (t^2) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutInQuad(qreal t) +{ + if (t < 0.5) return easeOutQuad (t*2)/2; + return easeInQuad((2*t)-1)/2 + 0.5; +} + +/** + * Easing equation function for a cubic (t^3) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInCubic(qreal t) +{ + return t*t*t; +} + +/** + * Easing equation function for a cubic (t^3) easing out: decelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutCubic(qreal t) +{ + t-=1.0; + return t*t*t + 1; +} + +/** + * Easing equation function for a cubic (t^3) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInOutCubic(qreal t) +{ + t*=2.0; + if(t < 1) { + return 0.5*t*t*t; + } else { + t -= qreal(2.0); + return 0.5*(t*t*t + 2); + } +} + +/** + * Easing equation function for a cubic (t^3) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutInCubic(qreal t) +{ + if (t < 0.5) return easeOutCubic (2*t)/2; + return easeInCubic(2*t - 1)/2 + 0.5; +} + +/** + * Easing equation function for a quartic (t^4) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInQuart(qreal t) +{ + return t*t*t*t; +} + +/** + * Easing equation function for a quartic (t^4) easing out: decelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutQuart(qreal t) +{ + t-= qreal(1.0); + return - (t*t*t*t- 1); +} + +/** + * Easing equation function for a quartic (t^4) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInOutQuart(qreal t) +{ + t*=2; + if (t < 1) return 0.5*t*t*t*t; + else { + t -= 2.0f; + return -0.5 * (t*t*t*t- 2); + } +} + +/** + * Easing equation function for a quartic (t^4) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutInQuart(qreal t) +{ + if (t < 0.5) return easeOutQuart (2*t)/2; + return easeInQuart(2*t-1)/2 + 0.5; +} + +/** + * Easing equation function for a quintic (t^5) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInQuint(qreal t) +{ + return t*t*t*t*t; +} + +/** + * Easing equation function for a quintic (t^5) easing out: decelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutQuint(qreal t) +{ + t-=1.0; + return t*t*t*t*t + 1; +} + +/** + * Easing equation function for a quintic (t^5) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInOutQuint(qreal t) +{ + t*=2.0; + if (t < 1) return 0.5*t*t*t*t*t; + else { + t -= 2.0; + return 0.5*(t*t*t*t*t + 2); + } +} + +/** + * Easing equation function for a quintic (t^5) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutInQuint(qreal t) +{ + if (t < 0.5) return easeOutQuint (2*t)/2; + return easeInQuint(2*t - 1)/2 + 0.5; +} + +/** + * Easing equation function for a sinusoidal (sin(t)) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInSine(qreal t) +{ + return (t == 1.0) ? 1.0 : -::cos(t * M_PI_2) + 1.0; +} + +/** + * Easing equation function for a sinusoidal (sin(t)) easing out: decelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutSine(qreal t) +{ + return ::sin(t* M_PI_2); +} + +/** + * Easing equation function for a sinusoidal (sin(t)) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInOutSine(qreal t) +{ + return -0.5 * (::cos(M_PI*t) - 1); +} + +/** + * Easing equation function for a sinusoidal (sin(t)) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutInSine(qreal t) +{ + if (t < 0.5) return easeOutSine (2*t)/2; + return easeInSine(2*t - 1)/2 + 0.5; +} + +/** + * Easing equation function for an exponential (2^t) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInExpo(qreal t) +{ + return (t==0 || t == 1.0) ? t : ::qPow(2.0, 10 * (t - 1)) - qreal(0.001); +} + +/** + * Easing equation function for an exponential (2^t) easing out: decelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutExpo(qreal t) +{ + return (t==1.0) ? 1.0 : 1.001 * (-::qPow(2.0f, -10 * t) + 1); +} + +/** + * Easing equation function for an exponential (2^t) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInOutExpo(qreal t) +{ + if (t==0.0) return qreal(0.0); + if (t==1.0) return qreal(1.0); + t*=2.0; + if (t < 1) return 0.5 * ::qPow(qreal(2.0), 10 * (t - 1)) - 0.0005; + return 0.5 * 1.0005 * (-::qPow(qreal(2.0), -10 * (t - 1)) + 2); +} + +/** + * Easing equation function for an exponential (2^t) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutInExpo(qreal t) +{ + if (t < 0.5) return easeOutExpo (2*t)/2; + return easeInExpo(2*t - 1)/2 + 0.5; +} + +/** + * Easing equation function for a circular (sqrt(1-t^2)) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInCirc(qreal t) +{ + return -(::sqrt(1 - t*t) - 1); +} + +/** + * Easing equation function for a circular (sqrt(1-t^2)) easing out: decelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutCirc(qreal t) +{ + t-= qreal(1.0); + return ::sqrt(1 - t* t); +} + +/** + * Easing equation function for a circular (sqrt(1-t^2)) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeInOutCirc(qreal t) +{ + t*=qreal(2.0); + if (t < 1) { + return -0.5 * (::sqrt(1 - t*t) - 1); + } else { + t -= qreal(2.0); + return 0.5 * (::sqrt(1 - t*t) + 1); + } +} + +/** + * Easing equation function for a circular (sqrt(1-t^2)) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @return The correct value. + */ +static qreal easeOutInCirc(qreal t) +{ + if (t < 0.5) return easeOutCirc (2*t)/2; + return easeInCirc(2*t - 1)/2 + 0.5; +} + +static qreal easeInElastic_helper(qreal t, qreal b, qreal c, qreal d, qreal a, qreal p) +{ + if (t==0) return b; + qreal t_adj = (qreal)t / (qreal)d; + if (t_adj==1) return b+c; + + qreal s; + if(a < ::fabs(c)) { + a = c; + s = p / 4.0f; + } else { + s = p / (2 * M_PI) * ::asin(c / a); + } + + t_adj -= 1.0f; + return -(a*::qPow(2.0f,10*t_adj) * ::sin( (t_adj*d-s)*(2*M_PI)/p )) + b; +} + +/** + * Easing equation function for an elastic (exponentially decaying sine wave) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @param a Amplitude. + * @param p Period. + * @return The correct value. + */ +static qreal easeInElastic(qreal t, qreal a, qreal p) +{ + return easeInElastic_helper(t, 0, 1, 1, a, p); +} + +static qreal easeOutElastic_helper(qreal t, qreal /*b*/, qreal c, qreal /*d*/, qreal a, qreal p) +{ + if (t==0) return 0; + if (t==1) return c; + + qreal s; + if(a < c) { + a = c; + s = p / 4.0f; + } else { + s = p / (2 * M_PI) * ::asin(c / a); + } + + return (a*::qPow(2.0f,-10*t) * ::sin( (t-s)*(2*M_PI)/p ) + c); +} + +/** + * Easing equation function for an elastic (exponentially decaying sine wave) easing out: decelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @param a Amplitude. + * @param p Period. + * @return The correct value. + */ +static qreal easeOutElastic(qreal t, qreal a, qreal p) +{ + return easeOutElastic_helper(t, 0, 1, 1, a, p); +} + +/** + * Easing equation function for an elastic (exponentially decaying sine wave) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @param a Amplitude. + * @param p Period. + * @return The correct value. + */ +static qreal easeInOutElastic(qreal t, qreal a, qreal p) +{ + if (t==0) return 0.0; + t*=2.0; + if (t==2) return 1.0; + + qreal s; + if(a < 1.0) { + a = 1.0; + s = p / 4.0f; + } else { + s = p / (2 * M_PI) * ::asin(1.0 / a); + } + + if (t < 1) return -.5*(a*::qPow(2.0f,10*(t-1)) * ::sin( (t-1-s)*(2*M_PI)/p )); + return a*::qPow(2.0f,-10*(t-1)) * ::sin( (t-1-s)*(2*M_PI)/p )*.5 + 1.0; +} + +/** + * Easing equation function for an elastic (exponentially decaying sine wave) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @param a Amplitude. + * @param p Period. + * @return The correct value. + */ +static qreal easeOutInElastic(qreal t, qreal a, qreal p) +{ + if (t < 0.5) return easeOutElastic_helper(t*2, 0, 0.5, 1.0, a, p); + return easeInElastic_helper(2*t - 1.0, 0.5, 0.5, 1.0, a, p); +} + +/** + * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). + * @return The correct value. + */ +static qreal easeInBack(qreal t, qreal s) +{ + return t*t*((s+1)*t - s); +} + +/** + * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out: decelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). + * @return The correct value. + */ +static qreal easeOutBack(qreal t, qreal s) +{ + t-= qreal(1.0); + return t*t*((s+1)*t+ s) + 1; +} + +/** + * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). + * @return The correct value. + */ +static qreal easeInOutBack(qreal t, qreal s) +{ + t *= 2.0; + if (t < 1) { + s *= 1.525f; + return 0.5*(t*t*((s+1)*t - s)); + } else { + t -= 2; + s *= 1.525f; + return 0.5*(t*t*((s+1)*t+ s) + 2); + } +} + +/** + * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). + * @return The correct value. + */ +static qreal easeOutInBack(qreal t, qreal s) +{ + if (t < 0.5) return easeOutBack (2*t, s)/2; + return easeInBack(2*t - 1, s)/2 + 0.5; +} + +static qreal easeOutBounce_helper(qreal t, qreal c, qreal a) +{ + if (t == 1.0) return c; + if (t < (4/11.0)) { + return c*(7.5625*t*t); + } else if (t < (8/11.0)) { + t -= (6/11.0); + return -a * (1. - (7.5625*t*t + .75)) + c; + } else if (t < (10/11.0)) { + t -= (9/11.0); + return -a * (1. - (7.5625*t*t + .9375)) + c; + } else { + t -= (21/22.0); + return -a * (1. - (7.5625*t*t + .984375)) + c; + } +} + +/** + * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: decelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @param a Amplitude. + * @return The correct value. + */ +static qreal easeOutBounce(qreal t, qreal a) +{ + return easeOutBounce_helper(t, 1, a); +} + +/** + * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in: accelerating from zero velocity. + * + * @param t Current time (in frames or seconds). + * @param a Amplitude. + * @return The correct value. + */ +static qreal easeInBounce(qreal t, qreal a) +{ + return 1.0 - easeOutBounce_helper(1.0-t, 1.0, a); +} + + +/** + * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in/out: acceleration until halfway, then deceleration. + * + * @param t Current time (in frames or seconds). + * @param a Amplitude. + * @return The correct value. + */ +static qreal easeInOutBounce(qreal t, qreal a) +{ + if (t < 0.5) return easeInBounce (2*t, a)/2; + else return (t == 1.0) ? 1.0 : easeOutBounce (2*t - 1, a)/2 + 0.5; +} + +/** + * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out/in: deceleration until halfway, then acceleration. + * + * @param t Current time (in frames or seconds). + * @param a Amplitude. + * @return The correct value. + */ +static qreal easeOutInBounce(qreal t, qreal a) +{ + if (t < 0.5) return easeOutBounce_helper(t*2, 0.5, a); + return 1.0 - easeOutBounce_helper (2.0-2*t, 0.5, a); +} + +static inline qreal qt_sinProgress(qreal value) +{ + return qSin((value * M_PI) - M_PI_2) / 2 + qreal(0.5); +} + +static inline qreal qt_smoothBeginEndMixFactor(qreal value) +{ + return qMin(qMax(1 - value * 2 + qreal(0.3), qreal(0.0)), qreal(1.0)); +} + +// SmoothBegin blends Smooth and Linear Interpolation. +// Progress 0 - 0.3 : Smooth only +// Progress 0.3 - ~ 0.5 : Mix of Smooth and Linear +// Progress ~ 0.5 - 1 : Linear only + +/** + * Easing function that starts growing slowly, then increases in speed. At the end of the curve the speed will be constant. + */ +static qreal easeInCurve(qreal t) +{ + const qreal sinProgress = qt_sinProgress(t); + const qreal mix = qt_smoothBeginEndMixFactor(t); + return sinProgress * mix + t * (1 - mix); +} + +/** + * Easing function that starts growing steadily, then ends slowly. The speed will be constant at the beginning of the curve. + */ +static qreal easeOutCurve(qreal t) +{ + const qreal sinProgress = qt_sinProgress(t); + const qreal mix = qt_smoothBeginEndMixFactor(1 - t); + return sinProgress * mix + t * (1 - mix); +} + +/** + * Easing function where the value grows sinusoidally. Note that the calculated end value will be 0 rather than 1. + */ +static qreal easeSineCurve(qreal t) +{ + return (qSin(((t * M_PI * 2)) - M_PI_2) + 1) / 2; +} + +/** + * Easing function where the value grows cosinusoidally. Note that the calculated start value will be 0.5 and the end value will be 0.5 + * contrary to the usual 0 to 1 easing curve. + */ +static qreal easeCosineCurve(qreal t) +{ + return (qCos(((t * M_PI * 2)) - M_PI_2) + 1) / 2; +} + diff --git a/src/3rdparty/easing/legal.qdoc b/src/3rdparty/easing/legal.qdoc new file mode 100644 index 0000000..25f67e1 --- /dev/null +++ b/src/3rdparty/easing/legal.qdoc @@ -0,0 +1,35 @@ +/*! +\page legal-easing.html +\title Easing Equations by Robert Penner +\ingroup animation + +\legalese +\code +Copyright (c) 2001 Robert Penner +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the author nor the names of contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\endcode +\endlegalese +*/ diff --git a/src/corelib/animation/animation.pri b/src/corelib/animation/animation.pri new file mode 100644 index 0000000..cb7850c --- /dev/null +++ b/src/corelib/animation/animation.pri @@ -0,0 +1,25 @@ +# Qt core animation module + +HEADERS += \ + animation/qabstractanimation.h \ + animation/qabstractanimation_p.h \ + animation/qvariantanimation.h \ + animation/qvariantanimation_p.h \ + animation/qpropertyanimation.h \ + animation/qpropertyanimation_p.h \ + animation/qanimationgroup.h \ + animation/qanimationgroup_p.h \ + animation/qsequentialanimationgroup.h \ + animation/qsequentialanimationgroup_p.h \ + animation/qparallelanimationgroup.h \ + animation/qparallelanimationgroup_p.h \ + animation/qpauseanimation.h + +SOURCES += \ + animation/qabstractanimation.cpp \ + animation/qvariantanimation.cpp \ + animation/qpropertyanimation.cpp \ + animation/qanimationgroup.cpp \ + animation/qsequentialanimationgroup.cpp \ + animation/qparallelanimationgroup.cpp \ + animation/qpauseanimation.cpp diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp new file mode 100644 index 0000000..94a94d1 --- /dev/null +++ b/src/corelib/animation/qabstractanimation.cpp @@ -0,0 +1,759 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QAbstractAnimation + \ingroup animation + \brief The QAbstractAnimation class is the base of all animations. + \since 4.6 + + The class defines the functions for the functionality shared by + all animations. By inheriting this class, you can create custom + animations that plug into the rest of the animation framework. + + The progress of an animation is given by its current time + (currentTime()), which is measured in milliseconds from the start + of the animation (0) to its end (duration()). The value is updated + automatically while the animation is running. It can also be set + directly with setCurrentTime(). + + At any point an animation is in one of three states: + \l{QAbstractAnimation::}{Running}, + \l{QAbstractAnimation::}{Stopped}, or + \l{QAbstractAnimation::}{Paused}--as defined by the + \l{QAbstractAnimation::}{State} enum. The current state can be + changed by calling start(), stop(), pause(), or resume(). An + animation will always reset its \l{currentTime()}{current time} + when it is started. If paused, it will continue with the same + current time when resumed. When an animation is stopped, it cannot + be resumed, but will keep its current time (until started again). + QAbstractAnimation will emit stateChanged() whenever its state + changes. + + An animation can loop any number of times by setting the loopCount + property. When an animation's current time reaches its duration(), + it will reset the current time and keep running. A loop count of 1 + (the default value) means that the animation will run one time. + Note that a duration of -1 means that the animation will run until + stopped; the current time will increase indefinitely. When the + current time equals duration() and the animation is in its + final loop, the \l{QAbstractAnimation::}{Stopped} state is + entered, and the finished() signal is emitted. + + QAbstractAnimation provides pure virtual functions used by + subclasses to track the progress of the animation: duration() and + updateCurrentTime(). The duration() function lets you report a + duration for the animation (as discussed above). The current time + is delivered by the animation framework through calls to + updateCurrentTime(). By reimplementing this function, you can + track the animation progress. Note that neither the interval + between calls nor the number of calls to this function are + defined; though, it will normally be 60 updates per second. + + By reimplementing updateState(), you can track the animation's + state changes, which is particularly useful for animations that + are not driven by time. + + \sa QVariantAnimation, QPropertyAnimation, QAnimationGroup, {The Animation Framework} +*/ + +/*! + \enum QAbstractAnimation::DeletionPolicy + + \value KeepWhenStopped The animation will not be deleted when stopped. + \value DeleteWhenStopped The animation will be automatically deleted when + stopped. +*/ + +/*! + \fn QAbstractAnimation::finished() + + QAbstractAnimation emits this signal after the animation has stopped and + has reached the end. + + This signal is emitted after stateChanged(). + + \sa stateChanged() +*/ + +/*! + \fn QAbstractAnimation::stateChanged(QAbstractAnimation::State oldState, QAbstractAnimation::State newState) + + QAbstractAnimation emits this signal whenever the state of the animation has + changed from \a oldState to \a newState. This signal is emitted after the virtual + updateState() function is called. + + \sa updateState() +*/ + +/*! + \fn QAbstractAnimation::currentLoopChanged(int currentLoop) + + QAbstractAnimation emits this signal whenever the current loop + changes. \a currentLoop is the current loop. + + \sa currentLoop(), loopCount() +*/ + +/*! + \fn QAbstractAnimation::directionChanged(QAbstractAnimation::Direction newDirection); + + QAbstractAnimation emits this signal whenever the direction has been + changed. \a newDirection is the new direction. + + \sa direction +*/ + +#ifndef QT_NO_ANIMATION + +#include "qabstractanimation.h" +#include "qanimationgroup.h" +#include + +#include "qabstractanimation_p.h" + +#include +#include +#include +#include + +#define DEFAULT_TIMER_INTERVAL 16 + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC(QThreadStorage, unifiedTimer); + +QUnifiedTimer::QUnifiedTimer() : QObject(), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL), consistentTiming(false) +{ +} + +QUnifiedTimer *QUnifiedTimer::instance() +{ + QUnifiedTimer *inst; + if (!unifiedTimer()->hasLocalData()) { + inst = new QUnifiedTimer; + unifiedTimer()->setLocalData(inst); + } else { + inst = unifiedTimer()->localData(); + } + return inst; +} + +void QUnifiedTimer::updateRecentlyStartedAnimations() +{ + if (animationsToStart.isEmpty()) + return; + + animations += animationsToStart; + updateTimer(); //we make sure we start the timer there + + animationsToStart.clear(); +} + +/* + defines the timing interval. Default is DEFAULT_TIMER_INTERVAL +*/ +void QUnifiedTimer::setTimingInterval(int interval) +{ + timingInterval = interval; + if (animationTimer.isActive()) { + //we changed the timing interval + animationTimer.start(timingInterval, this); + } +} + +/* + this allows to have a consistent timer interval at each tick from the timer + not taking the real time that passed into account. +*/ +void QUnifiedTimer::setConsistentTiming(bool b) +{ + consistentTiming = b; +} + +int QUnifiedTimer::elapsedTime() const +{ + return lastTick; +} + +void QUnifiedTimer::timerEvent(QTimerEvent *event) +{ + //this is simply the time we last received a tick + const int oldLastTick = lastTick; + if (time.isValid()) + lastTick = consistentTiming ? oldLastTick + timingInterval : time.elapsed(); + + //we transfer the waiting animations into the "really running" state + updateRecentlyStartedAnimations(); + + if (event->timerId() == startStopAnimationTimer.timerId()) { + startStopAnimationTimer.stop(); + if (animations.isEmpty()) { + animationTimer.stop(); + time = QTime(); + } else { + animationTimer.start(timingInterval, this); + lastTick = 0; + time.start(); + } + } else if (event->timerId() == animationTimer.timerId()) { + const int delta = lastTick - oldLastTick; + for (int i = 0; i < animations.count(); ++i) { + QAbstractAnimation *animation = animations.at(i); + int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime + + (animation->direction() == QAbstractAnimation::Forward ? delta : -delta); + animation->setCurrentTime(elapsed); + } + } +} + +void QUnifiedTimer::updateTimer() +{ + //we delay the call to start and stop for the animation timer so that if you + //stop and start animations in batch you don't stop/start the timer too often. + if (!startStopAnimationTimer.isActive()) + startStopAnimationTimer.start(0, this); // we delay the actual start of the animation +} + +void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation) +{ + if (animations.contains(animation) ||animationsToStart.contains(animation)) + return; + animationsToStart << animation; + updateTimer(); +} + +void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation) +{ + animations.removeAll(animation); + animationsToStart.removeAll(animation); + updateTimer(); +} + + +void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) +{ + Q_Q(QAbstractAnimation); + if (state == newState) + return; + + QAbstractAnimation::State oldState = state; + int oldCurrentTime = currentTime; + int oldCurrentLoop = currentLoop; + QAbstractAnimation::Direction oldDirection = direction; + + state = newState; + + QPointer guard(q); + + guard->updateState(oldState, newState); + + //this is to be safe if updateState changes the state + if (state == oldState) + return; + + // Notify state change + if (guard) + emit guard->stateChanged(oldState, newState); + + // Enter running state. + switch (state) + { + case QAbstractAnimation::Paused: + case QAbstractAnimation::Running: + { + // Rewind + if (oldState == QAbstractAnimation::Stopped) { + if (guard) { + if (direction == QAbstractAnimation::Forward) + q->setCurrentTime(0); + else + q->setCurrentTime(loopCount == -1 ? q->duration() : q->totalDuration()); + } + + // Check if the setCurrentTime() function called stop(). + // This can happen for a 0-duration animation + if (state == QAbstractAnimation::Stopped) + return; + } + + // Register timer if our parent is not running. + if (state == QAbstractAnimation::Running && guard) { + if (!group || group->state() == QAbstractAnimation::Stopped) { + QUnifiedTimer::instance()->registerAnimation(q); + } + } else { + //new state is paused + QUnifiedTimer::instance()->unregisterAnimation(q); + } + } + break; + case QAbstractAnimation::Stopped: + // Leave running state. + int dura = q->duration(); + if (deleteWhenStopped && guard) + q->deleteLater(); + + QUnifiedTimer::instance()->unregisterAnimation(q); + + if (dura == -1 || loopCount < 0 + || (oldDirection == QAbstractAnimation::Forward && (oldCurrentTime * (oldCurrentLoop + 1)) == (dura * loopCount)) + || (oldDirection == QAbstractAnimation::Backward && oldCurrentTime == 0)) { + if (guard) + emit q->finished(); + } + break; + } + +} + +/*! + Constructs the QAbstractAnimation base class, and passes \a parent to + QObject's constructor. + + \sa QVariantAnimation, QAnimationGroup +*/ +QAbstractAnimation::QAbstractAnimation(QObject *parent) + : QObject(*new QAbstractAnimationPrivate, 0) +{ + // Allow auto-add on reparent + setParent(parent); +} + +/*! + \internal +*/ +QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent) + : QObject(dd, 0) +{ + // Allow auto-add on reparent + setParent(parent); +} + +/*! + Stops the animation if it's running, then destroys the + QAbstractAnimation. If the animation is part of a QAnimationGroup, it is + automatically removed before it's destroyed. +*/ +QAbstractAnimation::~QAbstractAnimation() +{ + Q_D(QAbstractAnimation); + //we can't call stop here. Otherwise we get pure virtual calls + if (d->state != Stopped) { + QAbstractAnimation::State oldState = d->state; + d->state = Stopped; + emit stateChanged(oldState, d->state); + QUnifiedTimer::instance()->unregisterAnimation(this); + } +} + +/*! + \property QAbstractAnimation::state + \brief state of the animation. + + This property describes the current state of the animation. When the + animation state changes, QAbstractAnimation emits the stateChanged() + signal. +*/ +QAbstractAnimation::State QAbstractAnimation::state() const +{ + Q_D(const QAbstractAnimation); + return d->state; +} + +/*! + If this animation is part of a QAnimationGroup, this function returns a + pointer to the group; otherwise, it returns 0. + + \sa QAnimationGroup::addAnimation() +*/ +QAnimationGroup *QAbstractAnimation::group() const +{ + Q_D(const QAbstractAnimation); + return d->group; +} + +/*! + \enum QAbstractAnimation::State + + This enum describes the state of the animation. + + \value Stopped The animation is not running. This is the initial state + of QAbstractAnimation, and the state QAbstractAnimation reenters when finished. The current + time remain unchanged until either setCurrentTime() is + called, or the animation is started by calling start(). + + \value Paused The animation is paused (i.e., temporarily + suspended). Calling resume() will resume animation activity. + + \value Running The animation is running. While control is in the event + loop, QAbstractAnimation will update its current time at regular intervals, + calling updateCurrentTime() when appropriate. + + \sa state(), stateChanged() +*/ + +/*! + \enum QAbstractAnimation::Direction + + This enum describes the direction of the animation when in \l Running state. + + \value Forward The current time of the animation increases with time (i.e., + moves from 0 and towards the end / duration). + + \value Backward The current time of the animation decreases with time (i.e., + moves from the end / duration and towards 0). + + \sa direction +*/ + +/*! + \property QAbstractAnimation::direction + \brief the direction of the animation when it is in \l Running + state. + + This direction indicates whether the time moves from 0 towards the + animation duration, or from the value of the duration and towards 0 after + start() has been called. + + By default, this property is set to \l Forward. +*/ +QAbstractAnimation::Direction QAbstractAnimation::direction() const +{ + Q_D(const QAbstractAnimation); + return d->direction; +} +void QAbstractAnimation::setDirection(Direction direction) +{ + Q_D(QAbstractAnimation); + if (d->direction == direction) + return; + + d->direction = direction; + if (state() == Stopped) { + if (direction == Backward) { + d->currentTime = duration(); + d->currentLoop = d->loopCount - 1; + } else { + d->currentTime = 0; + d->currentLoop = 0; + } + } + updateDirection(direction); + emit directionChanged(direction); +} + +/*! + \property QAbstractAnimation::duration + \brief the duration of the animation. + + If the duration is -1, it means that the duration is undefined. + In this case, loopCount is ignored. +*/ + +/*! + \property QAbstractAnimation::loopCount + \brief the loop count of the animation + + This property describes the loop count of the animation as an integer. + By default this value is 1, indicating that the animation + should run once only, and then stop. By changing it you can let the + animation loop several times. With a value of 0, the animation will not + run at all, and with a value of -1, the animation will loop forever + until stopped. + It is not supported to have loop on an animation that has an undefined + duration. It will only run once. +*/ +int QAbstractAnimation::loopCount() const +{ + Q_D(const QAbstractAnimation); + return d->loopCount; +} +void QAbstractAnimation::setLoopCount(int loopCount) +{ + Q_D(QAbstractAnimation); + d->loopCount = loopCount; +} + +/*! + \property QAbstractAnimation::currentLoop + \brief the current loop of the animation + + This property describes the current loop of the animation. By default, + the animation's loop count is 1, and so the current loop will + always be 0. If the loop count is 2 and the animation runs past its + duration, it will automatically rewind and restart at current time 0, and + current loop 1, and so on. + + When the current loop changes, QAbstractAnimation emits the + currentLoopChanged() signal. +*/ +int QAbstractAnimation::currentLoop() const +{ + Q_D(const QAbstractAnimation); + return d->currentLoop; +} + +/*! + \fn virtual int QAbstractAnimation::duration() const = 0 + + This pure virtual function returns the duration of the animation, and + defines for how long QAbstractAnimation should update the current + time. This duration is local, and does not include the loop count. + + A return value of -1 indicates that the animation has no defined duration; + the animation should run forever until stopped. This is useful for + animations that are not time driven, or where you cannot easily predict + its duration (e.g., event driven audio playback in a game). + + If the animation is a parallel QAnimationGroup, the duration will be the longest + duration of all its animations. If the animation is a sequential QAnimationGroup, + the duration will be the sum of the duration of all its animations. + \sa loopCount +*/ + +/*! + Returns the total and effective duration of the animation, including the + loop count. + + \sa duration(), currentTime +*/ +int QAbstractAnimation::totalDuration() const +{ + Q_D(const QAbstractAnimation); + if (d->loopCount < 0) + return -1; + int dura = duration(); + if (dura == -1) + return -1; + return dura * d->loopCount; +} + +/*! + \property QAbstractAnimation::currentTime + \brief the current time and progress of the animation + + This property describes the animation's current time. You can change the + current time by calling setCurrentTime, or you can call start() and let + the animation run, setting the current time automatically as the animation + progresses. + + The animation's current time starts at 0, and ends at duration(). If the + animation's loopCount is larger than 1, the current time will rewind and + start at 0 again for the consecutive loops. If the animation has a pause. + currentTime will also include the duration of the pause. + + \sa loopCount + */ +int QAbstractAnimation::currentTime() const +{ + Q_D(const QAbstractAnimation); + return d->currentTime; +} +void QAbstractAnimation::setCurrentTime(int msecs) +{ + Q_D(QAbstractAnimation); + msecs = qMax(msecs, 0); + + // Calculate new time and loop. + int dura = duration(); + int totalDura = (d->loopCount < 0 || dura == -1) ? -1 : dura * d->loopCount; + if (totalDura != -1) + msecs = qMin(totalDura, msecs); + d->totalCurrentTime = msecs; + + // Update new values. + int oldLoop = d->currentLoop; + d->currentLoop = ((dura <= 0) ? 0 : (msecs / dura)); + if (d->currentLoop == d->loopCount) { + //we're at the end + d->currentTime = qMax(0, dura); + d->currentLoop = qMax(0, d->loopCount - 1); + } else { + if (d->direction == Forward) { + d->currentTime = (dura <= 0) ? msecs : (msecs % dura); + } else { + d->currentTime = (dura <= 0) ? msecs : ((msecs - 1) % dura) + 1; + if (d->currentTime == dura) + --d->currentLoop; + } + } + + updateCurrentTime(msecs); + if (d->currentLoop != oldLoop) + emit currentLoopChanged(d->currentLoop); + + // All animations are responsible for stopping the animation when their + // own end state is reached; in this case the animation is time driven, + // and has reached the end. + if ((d->direction == Forward && d->totalCurrentTime == totalDura) + || (d->direction == Backward && d->totalCurrentTime == 0)) { + stop(); + } +} + +/*! + Starts the animation. The \a policy argument says whether or not the + animation should be deleted when it's done. When the animation starts, the + stateChanged() signal is emitted, and state() returns Running. When control + reaches the event loop, the animation will run by itself, periodically + calling updateCurrentTime() as the animation progresses. + + If the animation is currently stopped or has already reached the end, + calling start() will rewind the animation and start again from the beginning. + When the animation reaches the end, the animation will either stop, or + if the loop level is more than 1, it will rewind and continue from the beginning. + + If the animation is already running, this function does nothing. + + \sa stop(), state() +*/ +void QAbstractAnimation::start(DeletionPolicy policy) +{ + Q_D(QAbstractAnimation); + if (d->state == Running) + return; + d->setState(Running); + d->deleteWhenStopped = policy; +} + +/*! + Stops the animation. When the animation is stopped, it emits the stateChanged() + signal, and state() returns Stopped. The current time is not changed. + + If the animation stops by itself after reaching the end (i.e., + currentTime() == duration() and currentLoop() > loopCount() - 1), the + finished() signal is emitted. + + \sa start(), state() + */ +void QAbstractAnimation::stop() +{ + Q_D(QAbstractAnimation); + + d->setState(Stopped); +} + +/*! + Pauses the animation. When the animation is paused, state() returns Paused. + The currenttime will remain unchanged until resume() or start() is called. + If you want to continue from the current time, call resume(). + + + \sa start(), state(), resume() + */ +void QAbstractAnimation::pause() +{ + Q_D(QAbstractAnimation); + if (d->state == Stopped) { + qWarning("QAbstractAnimation::pause: Cannot pause a stopped animation"); + return; + } + + d->setState(Paused); +} + +/*! + Resumes the animation after it was paused. When the animation is resumed, + it emits the resumed() and stateChanged() signals. The currenttime is not + changed. + + \sa start(), pause(), state() + */ +void QAbstractAnimation::resume() +{ + Q_D(QAbstractAnimation); + if (d->state != Paused) { + qWarning("QAbstractAnimation::resume: " + "Cannot resume an animation that is not paused"); + return; + } + + d->setState(Running); +} + +/*! + \reimp +*/ +bool QAbstractAnimation::event(QEvent *event) +{ + return QObject::event(event); +} + +/*! + \fn virtual void QAbstractAnimation::updateCurrentTime(int msecs) = 0; + + This pure virtual function is called every time the animation's current + time changes. The \a msecs argument is the current time. + + \sa updateState() +*/ + +/*! + This virtual function is called by QAbstractAnimation when the state + of the animation is changed from \a oldState to \a newState. + + \sa start(), stop(), pause(), resume() +*/ +void QAbstractAnimation::updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) +{ + Q_UNUSED(oldState); + Q_UNUSED(newState); +} + +/*! + This virtual function is called by QAbstractAnimation when the direction + of the animation is changed. The \a direction argument is the new direction. + + \sa setDirection(), direction() +*/ +void QAbstractAnimation::updateDirection(QAbstractAnimation::Direction direction) +{ + Q_UNUSED(direction); +} + + +QT_END_NAMESPACE + +#include "moc_qabstractanimation.cpp" + +#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h new file mode 100644 index 0000000..d6d50dc --- /dev/null +++ b/src/corelib/animation/qabstractanimation.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTANIMATION_H +#define QABSTRACTANIMATION_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +#ifndef QT_NO_ANIMATION + +class QAnimationGroup; +class QSequentialAnimationGroup; + +class QAbstractAnimationPrivate; +class Q_CORE_EXPORT QAbstractAnimation : public QObject +{ + Q_OBJECT + Q_PROPERTY(State state READ state NOTIFY stateChanged) + Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount) + Q_PROPERTY(int currentTime READ currentTime WRITE setCurrentTime) + Q_PROPERTY(int currentLoop READ currentLoop NOTIFY currentLoopChanged) + Q_PROPERTY(Direction direction READ direction WRITE setDirection NOTIFY directionChanged) + Q_PROPERTY(int duration READ duration) + +public: + enum Direction { + Forward, + Backward + }; + + enum State { + Stopped, + Paused, + Running + }; + + enum DeletionPolicy { + KeepWhenStopped = 0, + DeleteWhenStopped + }; + + QAbstractAnimation(QObject *parent = 0); + virtual ~QAbstractAnimation(); + + State state() const; + + QAnimationGroup *group() const; + + Direction direction() const; + void setDirection(Direction direction); + + int loopCount() const; + void setLoopCount(int loopCount); + int currentLoop() const; + + virtual int duration() const = 0; + int totalDuration() const; + + int currentTime() const; + +Q_SIGNALS: + void finished(); + void stateChanged(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); + void currentLoopChanged(int currentLoop); + void directionChanged(QAbstractAnimation::Direction); + +public Q_SLOTS: + void start(QAbstractAnimation::DeletionPolicy policy = KeepWhenStopped); + void pause(); + void resume(); + void stop(); + void setCurrentTime(int msecs); + +protected: + QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = 0); + bool event(QEvent *event); + + virtual void updateCurrentTime(int msecs) = 0; + virtual void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); + virtual void updateDirection(QAbstractAnimation::Direction direction); + +private: + Q_DISABLE_COPY(QAbstractAnimation) + Q_DECLARE_PRIVATE(QAbstractAnimation) +}; + +#endif //QT_NO_ANIMATION + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QABSTRACTANIMATION_H diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h new file mode 100644 index 0000000..e64554c --- /dev/null +++ b/src/corelib/animation/qabstractanimation_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTANIMATION_P_H +#define QABSTRACTANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of QIODevice. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QAnimationGroup; +class QAbstractAnimation; +class QAbstractAnimationPrivate : public QObjectPrivate +{ +public: + QAbstractAnimationPrivate() + : state(QAbstractAnimation::Stopped), + direction(QAbstractAnimation::Forward), + deleteWhenStopped(false), + totalCurrentTime(0), + currentTime(0), + loopCount(1), + currentLoop(0), + group(0) + { + } + + virtual ~QAbstractAnimationPrivate() {} + + static QAbstractAnimationPrivate *get(QAbstractAnimation *q) + { + return q->d_func(); + } + + QAbstractAnimation::State state; + QAbstractAnimation::Direction direction; + bool deleteWhenStopped; + void setState(QAbstractAnimation::State state); + + int totalCurrentTime; + int currentTime; + int loopCount; + int currentLoop; + + QAnimationGroup *group; + +private: + Q_DECLARE_PUBLIC(QAbstractAnimation) +}; + + +class Q_CORE_EXPORT QUnifiedTimer : public QObject +{ +private: + QUnifiedTimer(); + +public: + static QUnifiedTimer *instance(); + + void registerAnimation(QAbstractAnimation *animation); + void unregisterAnimation(QAbstractAnimation *animation); + + void setTimingInterval(int interval); + void setConsistentTiming(bool consistent); + + int elapsedTime() const; + +protected: + void timerEvent(QTimerEvent *); + void updateTimer(); + +private: + void updateRecentlyStartedAnimations(); + + QBasicTimer animationTimer, startStopAnimationTimer; + QTime time; + int lastTick; + int timingInterval; + bool consistentTiming; + QList animations, animationsToStart; +}; + +QT_END_NAMESPACE +#endif diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp new file mode 100644 index 0000000..ed06eff --- /dev/null +++ b/src/corelib/animation/qanimationgroup.cpp @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QAnimationGroup + \brief The QAnimationGroup class is an abstract base class for groups of animations. + \since 4.6 + \ingroup animation + + An animation group is a container for animations (subclasses of + QAbstractAnimation). A group is usually responsible for managing + the \l{QAbstractAnimation::State}{state} of its animations, i.e., + it decides when to start, stop, resume, and pause them. Currently, + Qt provides two such groups: QParallelAnimationGroup and + QSequentialAnimationGroup. Look up their class descriptions for + details. + + Since QAnimationGroup inherits from QAbstractAnimation, you can + combine groups, and easily construct complex animation graphs. + You can query QAbstractAnimation for the group it belongs to + (using the \l{QAbstractAnimation::}{group()} function). + + To start a top-level animation group, you simply use the + \l{QAbstractAnimation::}{start()} function from + QAbstractAnimation. By a top-level animation group, we think of a + group that itself is not contained within another group. Starting + sub groups directly is not supported, and may lead to unexpected + behavior. + + \omit OK, we'll put in a snippet on this here \endomit + + QAnimationGroup provides methods for adding and retrieving + animations. Besides that, you can remove animations by calling + remove(), and clear the animation group by calling + clearAnimations(). You may keep track of changes in the group's + animations by listening to QEvent::ChildAdded and + QEvent::ChildRemoved events. + + \omit OK, let's find a snippet here as well. \endomit + + QAnimationGroup takes ownership of the animations it manages, and + ensures that they are deleted when the animation group is deleted. + + You can also use a \l{The State Machine Framework}{state machine} + to create complex animations. The framework provides a special + state, QAnimationState, that plays an animation upon entry and + transitions to a new state when the animation has finished + playing. This technique can also be combined with using animation + groups. + + \sa QAbstractAnimation, QVariantAnimation, {The Animation Framework} +*/ + +#ifndef QT_NO_ANIMATION + +#include "qanimationgroup.h" +#include +#include +#include "qanimationgroup_p.h" + +QT_BEGIN_NAMESPACE + + +/*! + Constructs a QAnimationGroup. + \a parent is passed to QObject's constructor. +*/ +QAnimationGroup::QAnimationGroup(QObject *parent) + : QAbstractAnimation(*new QAnimationGroupPrivate, parent) +{ +} + +/*! + \internal +*/ +QAnimationGroup::QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent) + : QAbstractAnimation(dd, parent) +{ +} + +/*! + Destroys the animation group. It will also destroy all its animations. +*/ +QAnimationGroup::~QAnimationGroup() +{ +} + +/*! + Returns a pointer to the animation at \a index in this group. This + function is useful when you need access to a particular animation. \a + index is between 0 and animationCount() - 1. + + \sa animationCount(), indexOfAnimation() +*/ +QAbstractAnimation *QAnimationGroup::animationAt(int index) const +{ + Q_D(const QAnimationGroup); + + if (index < 0 || index >= d->animations.size()) { + qWarning("QAnimationGroup::animationAt: index is out of bounds"); + return 0; + } + + return d->animations.at(index); +} + + +/*! + Returns the number of animations managed by this group. + + \sa indexOfAnimation(), addAnimation(), animationAt() +*/ +int QAnimationGroup::animationCount() const +{ + Q_D(const QAnimationGroup); + return d->animations.size(); +} + +/*! + Returns the index of \a animation. The returned index can be passed + to the other functions that take an index as an argument. + + \sa insertAnimationAt(), animationAt(), takeAnimationAt() +*/ +int QAnimationGroup::indexOfAnimation(QAbstractAnimation *animation) const +{ + Q_D(const QAnimationGroup); + return d->animations.indexOf(animation); +} + +/*! + Adds \a animation to this group. This will call insertAnimationAt with + index equals to animationCount(). + + \note The group takes ownership of the animation. + + \sa removeAnimation() +*/ +void QAnimationGroup::addAnimation(QAbstractAnimation *animation) +{ + Q_D(QAnimationGroup); + insertAnimationAt(d->animations.count(), animation); +} + +/*! + Inserts \a animation into this animation group at \a index. + If \a index is 0 the animation is inserted at the beginning. + If \a index is animationCount(), the animation is inserted at the end. + + \note The group takes ownership of the animation. + + \sa takeAnimationAt(), addAnimation(), indexOfAnimation(), removeAnimation() +*/ +void QAnimationGroup::insertAnimationAt(int index, QAbstractAnimation *animation) +{ + Q_D(QAnimationGroup); + + if (index < 0 || index > d->animations.size()) { + qWarning("QAnimationGroup::insertAnimationAt: index is out of bounds"); + return; + } + + if (QAnimationGroup *oldGroup = animation->group()) + oldGroup->removeAnimation(animation); + + d->animations.insert(index, animation); + QAbstractAnimationPrivate::get(animation)->group = this; + // this will make sure that ChildAdded event is sent to 'this' + animation->setParent(this); + d->animationInsertedAt(index); +} + +/*! + Removes \a animation from this group. The ownership of \a animation is + transferred to the caller. + + \sa takeAnimationAt(), insertAnimationAt(), addAnimation() +*/ +void QAnimationGroup::removeAnimation(QAbstractAnimation *animation) +{ + Q_D(QAnimationGroup); + + if (!animation) { + qWarning("QAnimationGroup::remove: cannot remove null animation"); + return; + } + int index = d->animations.indexOf(animation); + if (index == -1) { + qWarning("QAnimationGroup::remove: animation is not part of this group"); + return; + } + + takeAnimationAt(index); +} + +/*! + Returns the animation at \a index and removes it from the animation group. + + \note The ownership of the animation is transferred to the caller. + + \sa removeAnimation(), addAnimation(), insertAnimation(), indexOfAnimation() +*/ +QAbstractAnimation *QAnimationGroup::takeAnimationAt(int index) +{ + Q_D(QAnimationGroup); + if (index < 0 || index >= d->animations.size()) { + qWarning("QAnimationGroup::takeAnimationAt: no animation at index %d", index); + return 0; + } + QAbstractAnimation *animation = d->animations.at(index); + QAbstractAnimationPrivate::get(animation)->group = 0; + // ### removing from list before doing setParent to avoid inifinite recursion + // in ChildRemoved event + d->animations.removeAt(index); + animation->setParent(0); + d->animationRemovedAt(index); + return animation; +} + +/*! + Removes and deletes all animations in this animation group, and resets the current + time to 0. + + \sa addAnimation(), removeAnimation() +*/ +void QAnimationGroup::clearAnimations() +{ + Q_D(QAnimationGroup); + qDeleteAll(d->animations); +} + +/*! + \reimp +*/ +bool QAnimationGroup::event(QEvent *event) +{ + Q_D(QAnimationGroup); + if (event->type() == QEvent::ChildAdded) { + QChildEvent *childEvent = static_cast(event); + if (QAbstractAnimation *a = qobject_cast(childEvent->child())) { + if (a->group() != this) + addAnimation(a); + } + } else if (event->type() == QEvent::ChildRemoved) { + QChildEvent *childEvent = static_cast(event); + QAbstractAnimation *a = static_cast(childEvent->child()); + // You can only rely on the child being a QObject because in the QEvent::ChildRemoved + // case it might be called from the destructor. + int index = d->animations.indexOf(a); + if (index != -1) + takeAnimationAt(index); + } + return QAbstractAnimation::event(event); +} + + +void QAnimationGroupPrivate::animationRemovedAt(int index) +{ + Q_Q(QAnimationGroup); + Q_UNUSED(index); + if (animations.isEmpty()) { + currentTime = 0; + q->stop(); + } +} + +QT_END_NAMESPACE + +#include "moc_qanimationgroup.cpp" + +#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qanimationgroup.h b/src/corelib/animation/qanimationgroup.h new file mode 100644 index 0000000..263bc38 --- /dev/null +++ b/src/corelib/animation/qanimationgroup.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANIMATIONGROUP_H +#define QANIMATIONGROUP_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +#ifndef QT_NO_ANIMATION + +class QAnimationGroupPrivate; +class Q_CORE_EXPORT QAnimationGroup : public QAbstractAnimation +{ + Q_OBJECT + +public: + QAnimationGroup(QObject *parent = 0); + ~QAnimationGroup(); + + QAbstractAnimation *animationAt(int index) const; + int animationCount() const; + int indexOfAnimation(QAbstractAnimation *animation) const; + void addAnimation(QAbstractAnimation *animation); + void insertAnimationAt(int index, QAbstractAnimation *animation); + void removeAnimation(QAbstractAnimation *animation); + QAbstractAnimation *takeAnimationAt(int index); + void clearAnimations(); + +protected: + QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent); + bool event(QEvent *event); + +private: + Q_DISABLE_COPY(QAnimationGroup) + Q_DECLARE_PRIVATE(QAnimationGroup) +}; + +#endif //QT_NO_ANIMATION + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //QANIMATIONGROUP_H diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h new file mode 100644 index 0000000..a7bd0fa --- /dev/null +++ b/src/corelib/animation/qanimationgroup_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANIMATIONGROUP_P_H +#define QANIMATIONGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of QIODevice. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qanimationgroup.h" + +#include + +#include "qabstractanimation_p.h" + +QT_BEGIN_NAMESPACE + +class QAnimationGroupPrivate : public QAbstractAnimationPrivate +{ + Q_DECLARE_PUBLIC(QAnimationGroup) +public: + QAnimationGroupPrivate() + { } + + virtual void animationInsertedAt(int index) { Q_UNUSED(index) }; + virtual void animationRemovedAt(int index); + + QList animations; +}; + +QT_END_NAMESPACE + +#endif //QANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp new file mode 100644 index 0000000..13f6073 --- /dev/null +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QParallelAnimationGroup + \brief The QParallelAnimationGroup class provides a parallel group of animations. + \since 4.6 + \ingroup animation + + QParallelAnimationGroup--a \l{QAnimationGroup}{container for + animations}--starts all its animations when it is + \l{QAbstractAnimation::start()}{started} itself, i.e., runs all + animations in parallel. The animation group finishes when the + longest lasting animation has finished. + + You can treat QParallelAnimation as any other QAbstractAnimation, + e.g., pause, resume, or add it to other animation groups. + + \code + QParallelAnimationGroup *group = new QParallelAnimationGroup; + group->addAnimation(anim1); + group->addAnimation(anim2); + + group->start(); + \endcode + + In this example, \c anim1 and \c anim2 are two + \l{QPropertyAnimation}s that have already been set up. + + \sa QAnimationGroup, QPropertyAnimation, {The Animation Framework} +*/ + +#ifndef QT_NO_ANIMATION + +#include "qparallelanimationgroup.h" +#include "qparallelanimationgroup_p.h" +//#define QANIMATION_DEBUG +QT_BEGIN_NAMESPACE + +/*! + Constructs a QParallelAnimationGroup. + \a parent is passed to QObject's constructor. +*/ +QParallelAnimationGroup::QParallelAnimationGroup(QObject *parent) + : QAnimationGroup(*new QParallelAnimationGroupPrivate, parent) +{ +} + +/*! + \internal +*/ +QParallelAnimationGroup::QParallelAnimationGroup(QParallelAnimationGroupPrivate &dd, + QObject *parent) + : QAnimationGroup(dd, parent) +{ +} + +/*! + Destroys the animation group. It will also destroy all its animations. +*/ +QParallelAnimationGroup::~QParallelAnimationGroup() +{ +} + +/*! + \reimp +*/ +int QParallelAnimationGroup::duration() const +{ + Q_D(const QParallelAnimationGroup); + int ret = 0; + + for (int i = 0; i < d->animations.size(); ++i) { + QAbstractAnimation *animation = d->animations.at(i); + const int currentDuration = animation->totalDuration(); + if (currentDuration == -1) + return -1; // Undetermined length + + ret = qMax(ret, currentDuration); + } + + return ret; +} + +/*! + \reimp +*/ +void QParallelAnimationGroup::updateCurrentTime(int) +{ + Q_D(QParallelAnimationGroup); + if (d->animations.isEmpty()) + return; + + if (d->currentLoop > d->lastLoop) { + // simulate completion of the loop + int dura = duration(); + if (dura > 0) { + foreach (QAbstractAnimation *animation, d->animations) { + animation->setCurrentTime(dura); // will stop + } + } + } else if (d->currentLoop < d->lastLoop) { + // simulate completion of the loop seeking backwards + foreach (QAbstractAnimation *animation, d->animations) { + animation->setCurrentTime(0); + animation->stop(); + } + } + + bool timeFwd = ((d->currentLoop == d->lastLoop && d->currentTime >= d->lastCurrentTime) + || d->currentLoop > d->lastLoop); +#ifdef QANIMATION_DEBUG + qDebug("QParallellAnimationGroup %5d: setCurrentTime(%d), loop:%d, last:%d, timeFwd:%d, lastcurrent:%d, %d", + __LINE__, d->currentTime, d->currentLoop, d->lastLoop, timeFwd, d->lastCurrentTime, state()); +#endif + // finally move into the actual time of the current loop + foreach (QAbstractAnimation *animation, d->animations) { + const int dura = animation->totalDuration(); + if (dura == -1 && d->isUncontrolledAnimationFinished(animation)) + continue; + if (dura == -1 || (d->currentTime <= dura && dura != 0) + || (dura == 0 && d->currentLoop != d->lastLoop)) { + switch (state()) { + case Running: + animation->start(); + break; + case Paused: + animation->pause(); + break; + case Stopped: + default: + break; + } + } + + if (dura <= 0) { + if (dura == -1) + animation->setCurrentTime(d->currentTime); + continue; + } + + if ((timeFwd && d->lastCurrentTime <= dura) + || (!timeFwd && d->currentTime <= dura)) + animation->setCurrentTime(d->currentTime); + if (d->currentTime > dura) + animation->stop(); + } + d->lastLoop = d->currentLoop; + d->lastCurrentTime = d->currentTime; +} + +/*! + \reimp +*/ +void QParallelAnimationGroup::updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) +{ + Q_D(QParallelAnimationGroup); + QAnimationGroup::updateState(oldState, newState); + + switch (newState) { + case Stopped: + foreach (QAbstractAnimation *animation, d->animations) + animation->stop(); + d->disconnectUncontrolledAnimations(); + break; + case Paused: + foreach (QAbstractAnimation *animation, d->animations) + animation->pause(); + break; + case Running: + d->connectUncontrolledAnimations(); + foreach (QAbstractAnimation *animation, d->animations) { + animation->stop(); + animation->setDirection(d->direction); + animation->start(); + } + break; + } +} + +void QParallelAnimationGroupPrivate::_q_uncontrolledAnimationFinished() +{ + Q_Q(QParallelAnimationGroup); + + QAbstractAnimation *animation = qobject_cast(q->sender()); + Q_ASSERT(animation); + + int uncontrolledRunningCount = 0; + if (animation->duration() == -1 || animation->loopCount() < 0) { + QHash::iterator it = uncontrolledFinishTime.begin(); + while (it != uncontrolledFinishTime.end()) { + if (it.key() == animation) { + *it = animation->currentTime(); + } + if (it.value() == -1) + ++uncontrolledRunningCount; + ++it; + } + } + + if (uncontrolledRunningCount > 0) + return; + + int maxDuration = 0; + foreach (QAbstractAnimation *a, animations) + maxDuration = qMax(maxDuration, a->totalDuration()); + + if (currentTime >= maxDuration) + q->stop(); +} + +void QParallelAnimationGroupPrivate::disconnectUncontrolledAnimations() +{ + Q_Q(QParallelAnimationGroup); + + QHash::iterator it = uncontrolledFinishTime.begin(); + while (it != uncontrolledFinishTime.end()) { + QObject::disconnect(it.key(), SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); + ++it; + } + + uncontrolledFinishTime.clear(); +} + +void QParallelAnimationGroupPrivate::connectUncontrolledAnimations() +{ + Q_Q(QParallelAnimationGroup); + + foreach (QAbstractAnimation *animation, animations) { + if (animation->duration() == -1 || animation->loopCount() < 0) { + uncontrolledFinishTime[animation] = -1; + QObject::connect(animation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); + } + } +} + +bool QParallelAnimationGroupPrivate::isUncontrolledAnimationFinished(QAbstractAnimation *anim) const +{ + return uncontrolledFinishTime.value(anim, -1) >= 0; +} + +/*! + \reimp +*/ +void QParallelAnimationGroup::updateDirection(QAbstractAnimation::Direction direction) +{ + Q_D(QParallelAnimationGroup); + //we need to update the direction of the current animation + if (state() != Stopped) { + foreach(QAbstractAnimation *anim, d->animations) { + anim->setDirection(direction); + } + } else { + if (direction == Forward) { + d->lastLoop = 0; + d->lastCurrentTime = 0; + } else { + // Looping backwards with loopCount == -1 does not really work well... + d->lastLoop = (d->loopCount == -1 ? 0 : d->loopCount - 1); + d->lastCurrentTime = duration(); + } + } +} + +/*! + \reimp +*/ +bool QParallelAnimationGroup::event(QEvent *event) +{ + return QAnimationGroup::event(event); +} + +QT_END_NAMESPACE + +#include "moc_qparallelanimationgroup.cpp" + +#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qparallelanimationgroup.h b/src/corelib/animation/qparallelanimationgroup.h new file mode 100644 index 0000000..57a8146 --- /dev/null +++ b/src/corelib/animation/qparallelanimationgroup.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPARALLELANIMATIONGROUP_H +#define QPARALLELANIMATIONGROUP_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +#ifndef QT_NO_ANIMATION + +class QParallelAnimationGroupPrivate; +class Q_CORE_EXPORT QParallelAnimationGroup : public QAnimationGroup +{ + Q_OBJECT + +public: + QParallelAnimationGroup(QObject *parent = 0); + ~QParallelAnimationGroup(); + + int duration() const; + +protected: + QParallelAnimationGroup(QParallelAnimationGroupPrivate &dd, QObject *parent); + bool event(QEvent *event); + + void updateCurrentTime(int msecs); + void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); + void updateDirection(QAbstractAnimation::Direction direction); + +private: + Q_DISABLE_COPY(QParallelAnimationGroup) + Q_DECLARE_PRIVATE(QParallelAnimationGroup) + Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished()) +}; + +#endif //QT_NO_ANIMATION + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QPARALLELANIMATIONGROUP diff --git a/src/corelib/animation/qparallelanimationgroup_p.h b/src/corelib/animation/qparallelanimationgroup_p.h new file mode 100644 index 0000000..f36d972 --- /dev/null +++ b/src/corelib/animation/qparallelanimationgroup_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPARALLELANIMATIONGROUP_P_H +#define QPARALLELANIMATIONGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of QIODevice. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qparallelanimationgroup.h" +#include "qanimationgroup_p.h" +#include + +QT_BEGIN_NAMESPACE + +class QParallelAnimationGroupPrivate : public QAnimationGroupPrivate +{ + Q_DECLARE_PUBLIC(QParallelAnimationGroup) +public: + QParallelAnimationGroupPrivate() + : lastLoop(0), lastCurrentTime(0) + { + } + + QHash uncontrolledFinishTime; + int lastLoop; + int lastCurrentTime; + + bool isUncontrolledAnimationFinished(QAbstractAnimation *anim) const; + void connectUncontrolledAnimations(); + void disconnectUncontrolledAnimations(); + + // private slot + void _q_uncontrolledAnimationFinished(); +}; + +QT_END_NAMESPACE + +#endif //QPARALLELANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qpauseanimation.cpp b/src/corelib/animation/qpauseanimation.cpp new file mode 100644 index 0000000..b175f0c --- /dev/null +++ b/src/corelib/animation/qpauseanimation.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QPauseAnimation + \brief The QPauseAnimation class provides a pause for QSequentialAnimationGroup. + \since 4.6 + \ingroup animation + + If you wish to introduce a delay between animations in a + QSequentialAnimationGroup, you can insert a QPauseAnimation. This + class does not animate anything, but does not + \l{QAbstractAnimation::finished()}{finish} before a specified + number of milliseconds have elapsed from when it was started. You + specify the duration of the pause in the constructor. It can also + be set directly with setDuration(). + + It is not necessary to construct a QPauseAnimation yourself. + QSequentialAnimationGroup provides the convenience functions + \l{QSequentialAnimationGroup::}{addPause()} and + \l{QSequentialAnimationGroup::}{insertPauseAt()}. These functions + simply take the number of milliseconds the pause should last. + + \sa QSequentialAnimationGroup +*/ + +#ifndef QT_NO_ANIMATION + +#include "qpauseanimation.h" +#include "qabstractanimation_p.h" + + +QT_BEGIN_NAMESPACE + +class QPauseAnimationPrivate : public QAbstractAnimationPrivate +{ +public: + QPauseAnimationPrivate() : QAbstractAnimationPrivate(), duration(0) + { + } + + int duration; +}; + +/*! + Constructs a QPauseAnimation. + \a parent is passed to QObject's constructor. + The default duration is 0. +*/ + +QPauseAnimation::QPauseAnimation(QObject *parent) : QAbstractAnimation(*new QPauseAnimationPrivate, parent) +{ +} + +/*! + Constructs a QPauseAnimation. + \a msecs is the duration of the pause. + \a parent is passed to QObject's constructor. +*/ + +QPauseAnimation::QPauseAnimation(int msecs, QObject *parent) : QAbstractAnimation(*new QPauseAnimationPrivate, parent) +{ + setDuration(msecs); +} + +/*! + Destroys the pause animation. +*/ +QPauseAnimation::~QPauseAnimation() +{ +} + +/*! + \property QPauseAnimation::duration + \brief the duration of the pause. + + The duration of the pause. The duration should not be negative. +*/ +int QPauseAnimation::duration() const +{ + Q_D(const QPauseAnimation); + return d->duration; +} + +void QPauseAnimation::setDuration(int msecs) +{ + if (msecs < 0) { + qWarning("QPauseAnimation::setDuration: cannot set a negative duration"); + return; + } + Q_D(QPauseAnimation); + d->duration = msecs; +} + +/*! + \reimp + */ +bool QPauseAnimation::event(QEvent *e) +{ + return QAbstractAnimation::event(e); +} + +/*! + \reimp + */ +void QPauseAnimation::updateCurrentTime(int msecs) +{ + Q_UNUSED(msecs); +} + + +QT_END_NAMESPACE + +#include "moc_qpauseanimation.cpp" + +#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qpauseanimation.h b/src/corelib/animation/qpauseanimation.h new file mode 100644 index 0000000..cb6e041 --- /dev/null +++ b/src/corelib/animation/qpauseanimation.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPAUSEANIMATION_P_H +#define QPAUSEANIMATION_P_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +#ifndef QT_NO_ANIMATION + +class QPauseAnimationPrivate; + +class Q_CORE_EXPORT QPauseAnimation : public QAbstractAnimation +{ + Q_OBJECT + Q_PROPERTY(int duration READ duration WRITE setDuration) +public: + QPauseAnimation(QObject *parent = 0); + QPauseAnimation(int msecs, QObject *parent = 0); + ~QPauseAnimation(); + + int duration() const; + void setDuration(int msecs); + +protected: + bool event(QEvent *e); + void updateCurrentTime(int msecs); + +private: + Q_DISABLE_COPY(QPauseAnimation) + Q_DECLARE_PRIVATE(QPauseAnimation) +}; + +#endif //QT_NO_ANIMATION + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QPAUSEANIMATION_P_H diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp new file mode 100644 index 0000000..9a17049 --- /dev/null +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QPropertyAnimation + \brief The QPropertyAnimation class animates Qt properties + \since 4.6 + \ingroup animation + + QPropertyAnimation interpolates over \l{Qt's Property System}{Qt + properties}. As property values are stored in \l{QVariant}s, the + class inherits QVariantAnimation, and supports animation of the + same \l{QVariant::Type}{variant types} as its super class. + + A class declaring properties must be a QObject. To make it + possible to animate a property, it must provide a setter (so that + QPropertyAnimation can set the property's value). Note that this + makes it possible to animate many of Qt's widgets. Let's look at + an example: + + \code + QPropertyAnimation animation(myWidget, "geometry"); + animation.setDuration(10000); + animation.setStartValue(QRect(0, 0, 100, 30)); + animation.setEndValue(QRect(250, 250, 100, 30)); + + animation.start(); + \endcode + + The property name and the QObject instance of which property + should be animated are passed to the constructor. You can then + specify the start and end value of the property. The procedure is + equal for properties in classes you have implemented + yourself--just check with QVariantAnimation that your QVariant + type is supported. + + The QVariantAnimation class description explains how to set up the + animation in detail. Note, however, that if a start value is not + set, the property will start at the value it had when the + QPropertyAnimation instance was created. + + QPropertyAnimation works like a charm on its own. For complex + animations that, for instance, contain several objects, + QAnimationGroup is provided. An animation group is an animation + that can contain other animations, and that can manage when its + animations are played. Look at QParallelAnimationGroup for an + example. + + \sa QVariantAnimation, QAnimationGroup, {The Animation Framework} +*/ + +#ifndef QT_NO_ANIMATION + +#include "qpropertyanimation.h" +#include "qanimationgroup.h" +#include + +#include "qpropertyanimation_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +typedef QPair QPropertyAnimationPair; +typedef QHash QPropertyAnimationHash; +Q_GLOBAL_STATIC(QPropertyAnimationHash, _q_runningAnimations); +Q_GLOBAL_STATIC_WITH_ARGS(QMutex, guardHashLock, (QMutex::Recursive) ) + +void QPropertyAnimationPrivate::updateMetaProperty() +{ + if (!target || propertyName.isEmpty()) + return; + + if (hasMetaProperty == 0 && !property.isValid()) { + const QMetaObject *mo = target->metaObject(); + propertyIndex = mo->indexOfProperty(propertyName); + if (propertyIndex != -1) { + hasMetaProperty = 1; + property = mo->property(propertyIndex); + propertyType = property.userType(); + } else { + if (!target->dynamicPropertyNames().contains(propertyName)) + qWarning("QPropertyAnimation: you're trying to animate a non-existing property %s of your QObject", propertyName.constData()); + hasMetaProperty = 2; + } + } + + if (property.isValid()) + convertValues(propertyType); +} + +void QPropertyAnimationPrivate::updateProperty(const QVariant &newValue) +{ + if (!target || state == QAbstractAnimation::Stopped) + return; + + if (hasMetaProperty == 1) { + if (newValue.userType() == propertyType) { + //no conversion is needed, we directly call the QObject::qt_metacall + void *data = const_cast(newValue.constData()); + target->qt_metacall(QMetaObject::WriteProperty, propertyIndex, &data); + } else { + property.write(target, newValue); + } + } else { + target->setProperty(propertyName.constData(), newValue); + } +} + +void QPropertyAnimationPrivate::_q_targetDestroyed() +{ + Q_Q(QPropertyAnimation); + //we stop here so that this animation is removed from the global hash + q->stop(); + target = 0; +} + +/*! + Construct a QPropertyAnimation object. \a parent is passed to QObject's + constructor. +*/ +QPropertyAnimation::QPropertyAnimation(QObject *parent) + : QVariantAnimation(*new QPropertyAnimationPrivate, parent) +{ +} + +/*! + Construct a QPropertyAnimation object. \a parent is passed to QObject's + constructor. The animation changes the property \a propertyName on \a + target. The default duration is 250ms. + + \sa targetObject, propertyName +*/ +QPropertyAnimation::QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent) + : QVariantAnimation(*new QPropertyAnimationPrivate, parent) +{ + setTargetObject(target); + setPropertyName(propertyName); +} + +/*! + Destroys the QPropertyAnimation instance. + */ +QPropertyAnimation::~QPropertyAnimation() +{ + stop(); +} + +/*! + \property QPropertyAnimation::targetObject + \brief the target QObject for this animation. + + This property defines the target QObject for this animation. + */ +QObject *QPropertyAnimation::targetObject() const +{ + Q_D(const QPropertyAnimation); + return d->target; +} + +void QPropertyAnimation::setTargetObject(QObject *target) +{ + Q_D(QPropertyAnimation); + if (d->target == target) + return; + + if (d->state != QAbstractAnimation::Stopped) { + qWarning("QPropertyAnimation::setTargetObject: you can't change the target of a running animation"); + return; + } + + //we need to get notified when the target is destroyed + if (d->target) + disconnect(d->target, SIGNAL(destroyed()), this, SLOT(_q_targetDestroyed())); + + if (target) + connect(target, SIGNAL(destroyed()), SLOT(_q_targetDestroyed())); + + d->target = target; + d->hasMetaProperty = 0; + d->updateMetaProperty(); +} + +/*! + \property QPropertyAnimation::propertyName + \brief the target property name for this animation + + This property defines the target property name for this animation. The + property name is required for the animation to operate. + */ +QByteArray QPropertyAnimation::propertyName() const +{ + Q_D(const QPropertyAnimation); + return d->propertyName; +} + +void QPropertyAnimation::setPropertyName(const QByteArray &propertyName) +{ + Q_D(QPropertyAnimation); + if (d->state != QAbstractAnimation::Stopped) { + qWarning("QPropertyAnimation::setPropertyName: you can't change the property name of a running animation"); + return; + } + + d->propertyName = propertyName; + d->hasMetaProperty = 0; + d->updateMetaProperty(); +} + + +/*! + \reimp + */ +bool QPropertyAnimation::event(QEvent *event) +{ + return QVariantAnimation::event(event); +} + +/*! + This virtual function is called by QVariantAnimation whenever the current value + changes. \a value is the new, updated value. It updates the current value + of the property on the target object. + + \sa currentValue, currentTime + */ +void QPropertyAnimation::updateCurrentValue(const QVariant &value) +{ + Q_D(QPropertyAnimation); + d->updateProperty(value); +} + +/*! + \reimp + + If the startValue is not defined when the state of the animation changes from Stopped to Running, + the current property value is used as the initial value for the animation. +*/ +void QPropertyAnimation::updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) +{ + Q_D(QPropertyAnimation); + + if (!d->target) { + qWarning("QPropertyAnimation::updateState: Changing state of an animation without target"); + return; + } + + QVariantAnimation::updateState(oldState, newState); + QMutexLocker locker(guardHashLock()); + QPropertyAnimationHash * hash = _q_runningAnimations(); + QPropertyAnimationPair key(d->target, d->propertyName); + if (newState == Running) { + d->updateMetaProperty(); + QPropertyAnimation *oldAnim = hash->value(key, 0); + if (oldAnim) { + // try to stop the top level group + QAbstractAnimation *current = oldAnim; + while (current->group() && current->state() != Stopped) + current = current->group(); + current->stop(); + } + hash->insert(key, this); + + // update the default start value + if (oldState == Stopped) { + d->setDefaultStartValue(d->target->property(d->propertyName.constData())); + } + } else if (hash->value(key) == this) { + hash->remove(key); + } +} + +#include "moc_qpropertyanimation.cpp" + +QT_END_NAMESPACE + +#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h new file mode 100644 index 0000000..5b06bd2 --- /dev/null +++ b/src/corelib/animation/qpropertyanimation.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPROPERTYANIMATION_H +#define QPROPERTYANIMATION_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +#ifndef QT_NO_ANIMATION + +class QPropertyAnimationPrivate; +class Q_CORE_EXPORT QPropertyAnimation : public QVariantAnimation +{ + Q_OBJECT + Q_PROPERTY(QByteArray propertyName READ propertyName WRITE setPropertyName) + Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject) + +public: + QPropertyAnimation(QObject *parent = 0); + QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0); + ~QPropertyAnimation(); + + QObject *targetObject() const; + void setTargetObject(QObject *target); + + QByteArray propertyName() const; + void setPropertyName(const QByteArray &propertyName); + +protected: + bool event(QEvent *event); + + void updateCurrentValue(const QVariant &value); + void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); + Q_PRIVATE_SLOT(d_func(), void _q_targetDestroyed()); +private: + Q_DISABLE_COPY(QPropertyAnimation) + Q_DECLARE_PRIVATE(QPropertyAnimation) +}; + +#endif //QT_NO_ANIMATION + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QPROPERTYANIMATION_H diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h new file mode 100644 index 0000000..b51d039 --- /dev/null +++ b/src/corelib/animation/qpropertyanimation_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPROPERTYANIMATION_P_H +#define QPROPERTYANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of QIODevice. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qpropertyanimation.h" +#include + +#include "qvariantanimation_p.h" + +QT_BEGIN_NAMESPACE + +class QPropertyAnimationPrivate : public QVariantAnimationPrivate +{ + Q_DECLARE_PUBLIC(QPropertyAnimation) +public: + QPropertyAnimationPrivate() + : target(0), propertyType(0), propertyIndex(0), hasMetaProperty(false) + { + } + + void _q_targetDestroyed(); + + QObject *target; + + //for the QProperty + QMetaProperty property; + int propertyType; + int propertyIndex; + + int hasMetaProperty; + QByteArray propertyName; + void updateProperty(const QVariant &); + void updateMetaProperty(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp new file mode 100644 index 0000000..14814a7 --- /dev/null +++ b/src/corelib/animation/qsequentialanimationgroup.cpp @@ -0,0 +1,594 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QSequentialAnimationGroup + \brief The QSequentialAnimationGroup class provides a sequential group of animations. + \since 4.6 + \ingroup animation + + QSequentialAnimationGroup is a QAnimationGroup that runs its + animations in sequence, i.e., it starts one animation after + another has finished playing. The animations are played in the + order they are added to the group (using + \l{QAnimationGroup::}{addAnimation()} or + \l{QAnimationGroup::}{insertAnimationAt()}). The animation group + finishes when its last animation has finished. + + At each moment there is at most one animation that is active in + the group; it is returned by currentAnimation(). An empty group + has no current animation. + + A sequential animation group can be treated as any other + animation, i.e., it can be started, stopped, and added to other + groups. You can also call addPause() or insertPauseAt() to add a + pause to a sequential animation group. + + \code + QSequentialAnimationGroup group; + + group.addAnimation(anim1); + group.addAnimation(anim2); + + group.start(); + \endcode + + In this example, \c anim1 and \c anim2 are two already set up + \l{QPropertyAnimation}s. + + \sa QAnimationGroup, QAbstractAnimation, {The Animation Framework} +*/ + +#ifndef QT_NO_ANIMATION + +#include "qsequentialanimationgroup.h" +#include "qsequentialanimationgroup_p.h" + +#include "qpauseanimation.h" + +#include + +QT_BEGIN_NAMESPACE + + + +bool QSequentialAnimationGroupPrivate::atEnd() const +{ + // we try to detect if we're at the end of the group + //this is true if the following conditions are true: + // 1. we're in the last loop + // 2. the direction is forward + // 3. the current animation is the last one + // 4. the current animation has reached its end + const int animTotalCurrentTime = QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime; + return (currentLoop == loopCount - 1 + && direction == QAbstractAnimation::Forward + && currentAnimation == animations.last() + && animTotalCurrentTime == animationActualTotalDuration(currentAnimationIndex)); +} + +int QSequentialAnimationGroupPrivate::animationActualTotalDuration(int index) const +{ + QAbstractAnimation *anim = animations.at(index); + int ret = anim->totalDuration(); + if (ret == -1 && actualDuration.size() > index) + ret = actualDuration.at(index); //we can try the actual duration there + return ret; +} + +QSequentialAnimationGroupPrivate::AnimationIndex QSequentialAnimationGroupPrivate::indexForTime(int msecs) const +{ + Q_Q(const QSequentialAnimationGroup); + Q_ASSERT(!animations.isEmpty()); + + AnimationIndex ret; + int duration = 0; + + // in case duration is -1, currentLoop will always be 0 + ret.timeOffset = currentLoop * q->duration(); + + for (int i = 0; i < animations.size(); ++i) { + duration = animationActualTotalDuration(i); + + // 'animation' is the current animation if one of these reasons is true: + // 1. it's duration is undefined + // 2. it ends after msecs + // 3. it is the last animation (this can happen in case there is at least 1 uncontrolled animation) + // 4. it ends exactly in msecs and the direction is backwards + if (duration == -1 || msecs < (ret.timeOffset + duration) + || (msecs == (ret.timeOffset + duration) && direction == QAbstractAnimation::Backward)) { + ret.index = i; + return ret; + } + + // 'animation' has a non-null defined duration and is not the one at time 'msecs'. + ret.timeOffset += duration; + } + + // this can only happen when one of those conditions is true: + // 1. the duration of the group is undefined and we passed its actual duration + // 2. there are only 0-duration animations in the group + ret.timeOffset -= duration; + ret.index = animations.size() - 1; + return ret; +} + +void QSequentialAnimationGroupPrivate::restart() +{ + // restarting the group by making the first/last animation the current one + if (direction == QAbstractAnimation::Forward) { + lastLoop = 0; + if (currentAnimationIndex == 0) + activateCurrentAnimation(); + else + setCurrentAnimation(0); + } else { // direction == QAbstractAnimation::Backward + lastLoop = loopCount - 1; + int index = animations.size() - 1; + if (currentAnimationIndex == index) + activateCurrentAnimation(); + else + setCurrentAnimation(index); + } +} + +/*! + \internal + This manages advancing the execution of a group running forwards (time has gone forward), + which is the same behaviour for rewinding the execution of a group running backwards + (time has gone backward). +*/ +void QSequentialAnimationGroupPrivate::advanceForwards(const AnimationIndex &newAnimationIndex) +{ + if (lastLoop < currentLoop) { + // we need to fast forward to the end + for (int i = currentAnimationIndex; i < animations.size(); ++i) { + QAbstractAnimation *anim = animations.at(i); + setCurrentAnimation(i, true); + anim->setCurrentTime(animationActualTotalDuration(i)); + } + // this will make sure the current animation is reset to the beginning + if (animations.size() == 1) + // we need to force activation because setCurrentAnimation will have no effect + activateCurrentAnimation(); + else + setCurrentAnimation(0, true); + } + + // and now we need to fast forward from the current position to + for (int i = currentAnimationIndex; i < newAnimationIndex.index; ++i) { //### WRONG, + QAbstractAnimation *anim = animations.at(i); + setCurrentAnimation(i, true); + anim->setCurrentTime(animationActualTotalDuration(i)); + } + // setting the new current animation will happen later +} + +/*! + \internal + This manages rewinding the execution of a group running forwards (time has gone forward), + which is the same behaviour for advancing the execution of a group running backwards + (time has gone backward). +*/ +void QSequentialAnimationGroupPrivate::rewindForwards(const AnimationIndex &newAnimationIndex) +{ + if (lastLoop > currentLoop) { + // we need to fast rewind to the beginning + for (int i = currentAnimationIndex; i >= 0 ; --i) { + QAbstractAnimation *anim = animations.at(i); + setCurrentAnimation(i, true); + anim->setCurrentTime(0); + } + // this will make sure the current animation is reset to the end + if (animations.size() == 1) + // we need to force activation because setCurrentAnimation will have no effect + activateCurrentAnimation(); + else + setCurrentAnimation(animations.count() - 1, true); + } + + // and now we need to fast rewind from the current position to + for (int i = currentAnimationIndex; i > newAnimationIndex.index; --i) { + QAbstractAnimation *anim = animations.at(i); + setCurrentAnimation(i, true); + anim->setCurrentTime(0); + } + // setting the new current animation will happen later +} + +/*! + \fn QSequentialAnimationGroup::currentAnimationChanged(QAbstractAnimation *current) + + QSequentialAnimationGroup emits this signal when currentAnimation + has been changed. \a current is the current animation. + + \sa currentAnimation() +*/ + + +/*! + Constructs a QSequentialAnimationGroup. + \a parent is passed to QObject's constructor. +*/ +QSequentialAnimationGroup::QSequentialAnimationGroup(QObject *parent) + : QAnimationGroup(*new QSequentialAnimationGroupPrivate, parent) +{ +} + +/*! + \internal +*/ +QSequentialAnimationGroup::QSequentialAnimationGroup(QSequentialAnimationGroupPrivate &dd, + QObject *parent) + : QAnimationGroup(dd, parent) +{ +} + +/*! + Destroys the animation group. It will also destroy all its animations. +*/ +QSequentialAnimationGroup::~QSequentialAnimationGroup() +{ +} + +/*! + Adds a pause of \a msecs to this animation group. + The pause is considered as a special type of animation, thus count() will be + increased by one. + \sa insertPauseAt(), QAnimationGroup::addAnimation() +*/ +QPauseAnimation *QSequentialAnimationGroup::addPause(int msecs) +{ + QPauseAnimation *pause = new QPauseAnimation(msecs); + addAnimation(pause); + return pause; +} + +/*! + Inserts a pause of \a msecs milliseconds at \a index in this animation + group. + + \sa addPause(), QAnimationGroup::insertAnimationAt() +*/ +QPauseAnimation *QSequentialAnimationGroup::insertPauseAt(int index, int msecs) +{ + Q_D(const QSequentialAnimationGroup); + + if (index < 0 || index > d->animations.size()) { + qWarning("QSequentialAnimationGroup::insertPauseAt: index is out of bounds"); + return 0; + } + + QPauseAnimation *pause = new QPauseAnimation(msecs); + insertAnimationAt(index, pause); + return pause; +} + + +/*! + \property QSequentialAnimationGroup::currentAnimation + Returns the animation in the current time. + + \sa currentAnimationChanged() +*/ +QAbstractAnimation *QSequentialAnimationGroup::currentAnimation() const +{ + Q_D(const QSequentialAnimationGroup); + return d->currentAnimation; +} + +/*! + \reimp +*/ +int QSequentialAnimationGroup::duration() const +{ + Q_D(const QSequentialAnimationGroup); + int ret = 0; + + for (int i = 0; i < d->animations.size(); ++i) { + QAbstractAnimation *animation = d->animations.at(i); + const int currentDuration = animation->totalDuration(); + if (currentDuration == -1) + return -1; // Undetermined length + + ret += currentDuration; + } + + return ret; +} + +/*! + \reimp +*/ +void QSequentialAnimationGroup::updateCurrentTime(int msecs) +{ + Q_D(QSequentialAnimationGroup); + if (!d->currentAnimation) + return; + + const QSequentialAnimationGroupPrivate::AnimationIndex newAnimationIndex = d->indexForTime(msecs); + + // remove unneeded animations from actualDuration list + while (newAnimationIndex.index < d->actualDuration.size()) + d->actualDuration.removeLast(); + + // newAnimationIndex.index is the new current animation + if (d->lastLoop < d->currentLoop + || (d->lastLoop == d->currentLoop && d->currentAnimationIndex < newAnimationIndex.index)) { + // advancing with forward direction is the same as rewinding with backwards direction + d->advanceForwards(newAnimationIndex); + } else if (d->lastLoop > d->currentLoop + || (d->lastLoop == d->currentLoop && d->currentAnimationIndex > newAnimationIndex.index)) { + // rewinding with forward direction is the same as advancing with backwards direction + d->rewindForwards(newAnimationIndex); + } + + d->setCurrentAnimation(newAnimationIndex.index); + + const int newCurrentTime = msecs - newAnimationIndex.timeOffset; + + if (d->currentAnimation) { + d->currentAnimation->setCurrentTime(newCurrentTime); + if (d->atEnd()) { + //we make sure that we don't exceed the duration here + d->currentTime += QAbstractAnimationPrivate::get(d->currentAnimation)->totalCurrentTime - newCurrentTime; + stop(); + } + } else { + //the only case where currentAnimation could be null + //is when all animations have been removed + Q_ASSERT(d->animations.isEmpty()); + d->currentTime = 0; + stop(); + } + + d->lastLoop = d->currentLoop; +} + +/*! + \reimp +*/ +void QSequentialAnimationGroup::updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) +{ + Q_D(QSequentialAnimationGroup); + QAnimationGroup::updateState(oldState, newState); + + if (!d->currentAnimation) + return; + + switch (newState) { + case Stopped: + d->currentAnimation->stop(); + break; + case Paused: + if (oldState == d->currentAnimation->state() + && oldState == QSequentialAnimationGroup::Running) { + d->currentAnimation->pause(); + } + else + d->restart(); + break; + case Running: + if (oldState == d->currentAnimation->state() + && oldState == QSequentialAnimationGroup::Paused) + d->currentAnimation->start(); + else + d->restart(); + break; + } +} + +/*! + \reimp +*/ +void QSequentialAnimationGroup::updateDirection(QAbstractAnimation::Direction direction) +{ + Q_D(QSequentialAnimationGroup); + // we need to update the direction of the current animation + if (state() != Stopped && d->currentAnimation) + d->currentAnimation->setDirection(direction); +} + +/*! + \reimp +*/ +bool QSequentialAnimationGroup::event(QEvent *event) +{ + return QAnimationGroup::event(event); +} + +void QSequentialAnimationGroupPrivate::setCurrentAnimation(int index, bool intermediate) +{ + Q_Q(QSequentialAnimationGroup); + + index = qMin(index, animations.count() - 1); + + if (index == -1) { + Q_ASSERT(animations.isEmpty()); + currentAnimationIndex = -1; + currentAnimation = 0; + return; + } + + // need these two checks below because this func can be called after the current animation + // has been removed + if (index == currentAnimationIndex && animations.at(index) == currentAnimation) + return; + + // stop the old current animation + if (currentAnimation) + currentAnimation->stop(); + + currentAnimation = animations.at(index); + currentAnimationIndex = index; + + emit q->currentAnimationChanged(currentAnimation); + + activateCurrentAnimation(intermediate); +} + +void QSequentialAnimationGroupPrivate::activateCurrentAnimation(bool intermediate) +{ + Q_Q(QSequentialAnimationGroup); + + if (!currentAnimation) + return; + + if (state == QSequentialAnimationGroup::Stopped) + return; + + currentAnimation->stop(); + + // we ensure the direction is consistent with the group's direction + currentAnimation->setDirection(direction); + + // connects to the finish signal of uncontrolled animations + if (currentAnimation->totalDuration() == -1) + QObject::connect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); + + currentAnimation->start(); + if (!intermediate && state == QSequentialAnimationGroup::Paused) + currentAnimation->pause(); +} + +void QSequentialAnimationGroupPrivate::_q_uncontrolledAnimationFinished() +{ + Q_Q(QSequentialAnimationGroup); + Q_ASSERT(qobject_cast(q->sender()) == currentAnimation); + + // we trust the duration returned by the animation + while (actualDuration.size() < (currentAnimationIndex + 1)) + actualDuration.append(-1); + actualDuration[currentAnimationIndex] = currentAnimation->currentTime(); + + QObject::disconnect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); + + if ((direction == QAbstractAnimation::Forward && currentAnimation == animations.last()) + || (direction == QAbstractAnimation::Backward && currentAnimationIndex == 0)) { + // we don't handle looping of a group with undefined duration + q->stop(); + } else if (direction == QAbstractAnimation::Forward) { + // set the current animation to be the next one + setCurrentAnimation(currentAnimationIndex + 1); + } else { + // set the current animation to be the previous one + setCurrentAnimation(currentAnimationIndex - 1); + } +} + +/*! + \internal + This method is called whenever an animation is added to + the group at index \a index. + Note: We only support insertion after the current animation +*/ +void QSequentialAnimationGroupPrivate::animationInsertedAt(int index) +{ + if (currentAnimation == 0) + setCurrentAnimation(0); // initialize the current animation + + if (currentAnimationIndex == index + && currentAnimation->currentTime() == 0 && currentAnimation->currentLoop() == 0) { + //in this case we simply insert an animation before the current one has actually started + setCurrentAnimation(index); + } + + //we update currentAnimationIndex in case it has changed (the animation pointer is still valid) + currentAnimationIndex = animations.indexOf(currentAnimation); + + if (index < currentAnimationIndex || currentLoop != 0) { + qWarning("QSequentialGroup::insertAnimationAt only supports to add animations after the current one."); + return; //we're not affected because it is added after the current one + } +} + +/*! + \internal + This method is called whenever an animation is removed from + the group at index \a index. The animation is no more listed when this + method is called. +*/ +void QSequentialAnimationGroupPrivate::animationRemovedAt(int index) +{ + Q_Q(QSequentialAnimationGroup); + QAnimationGroupPrivate::animationRemovedAt(index); + + Q_ASSERT(currentAnimation); // currentAnimation should always be set + + if (actualDuration.size() > index) + actualDuration.removeAt(index); + + const int currentIndex = animations.indexOf(currentAnimation); + if (currentIndex == -1) { + //we're removing the current animation, let's update it to another one + if (index < animations.count()) + setCurrentAnimation(index); //let's try to take the next one + else if (index > 0) + setCurrentAnimation(index - 1); + else// case all animations were removed + setCurrentAnimation(-1); + } else if (currentAnimationIndex > index) { + currentAnimationIndex--; + } + + // duration of the previous animations up to the current animation + currentTime = 0; + for (int i = 0; i < currentAnimationIndex; ++i) { + const int current = animationActualTotalDuration(i); + currentTime += current; + } + + if (currentIndex != -1) { + //the current animation is not the one being removed + //so we add its current time to the current time of this group + currentTime += QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime; + } + + //let's also update the total current time + totalCurrentTime = currentTime + loopCount * q->duration(); +} + +QT_END_NAMESPACE + +#include "moc_qsequentialanimationgroup.cpp" + +#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qsequentialanimationgroup.h b/src/corelib/animation/qsequentialanimationgroup.h new file mode 100644 index 0000000..4701a76 --- /dev/null +++ b/src/corelib/animation/qsequentialanimationgroup.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSEQUENTIALANIMATIONGROUP_H +#define QSEQUENTIALANIMATIONGROUP_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +#ifndef QT_NO_ANIMATION + +class QPauseAnimation; +class QSequentialAnimationGroupPrivate; + +class Q_CORE_EXPORT QSequentialAnimationGroup : public QAnimationGroup +{ + Q_OBJECT + Q_PROPERTY(QAbstractAnimation* currentAnimation READ currentAnimation NOTIFY currentAnimationChanged) + +public: + QSequentialAnimationGroup(QObject *parent = 0); + ~QSequentialAnimationGroup(); + + QPauseAnimation *addPause(int msecs); + QPauseAnimation *insertPauseAt(int index, int msecs); + + QAbstractAnimation *currentAnimation() const; + int duration() const; + +Q_SIGNALS: + void currentAnimationChanged(QAbstractAnimation *current); + +protected: + QSequentialAnimationGroup(QSequentialAnimationGroupPrivate &dd, QObject *parent); + bool event(QEvent *event); + + void updateCurrentTime(int msecs); + void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); + void updateDirection(QAbstractAnimation::Direction direction); + +private: + Q_DISABLE_COPY(QSequentialAnimationGroup) + Q_DECLARE_PRIVATE(QSequentialAnimationGroup) + Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished()) +}; + +#endif //QT_NO_ANIMATION + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //QSEQUENTIALANIMATIONGROUP_H diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h new file mode 100644 index 0000000..3ac90f8 --- /dev/null +++ b/src/corelib/animation/qsequentialanimationgroup_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSEQUENTIALANIMATIONGROUP_P_H +#define QSEQUENTIALANIMATIONGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of QIODevice. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qsequentialanimationgroup.h" +#include "qanimationgroup_p.h" + + +QT_BEGIN_NAMESPACE + +class QSequentialAnimationGroupPrivate : public QAnimationGroupPrivate +{ + Q_DECLARE_PUBLIC(QSequentialAnimationGroup) +public: + QSequentialAnimationGroupPrivate() + : currentAnimation(0), currentAnimationIndex(-1), lastLoop(0) + { } + + + struct AnimationIndex + { + AnimationIndex() : index(0), timeOffset(0) {} + // index points to the animation at timeOffset, skipping 0 duration animations. + // Note that the index semantic is slightly different depending on the direction. + int index; // the index of the animation in timeOffset + int timeOffset; // time offset when the animation at index starts. + }; + + int animationActualTotalDuration(int index) const; + AnimationIndex indexForTime(int msecs) const; + + void setCurrentAnimation(int index, bool intermediate = false); + void activateCurrentAnimation(bool intermediate = false); + + void animationInsertedAt(int index); + void animationRemovedAt(int index); + + bool atEnd() const; + + QAbstractAnimation *currentAnimation; + int currentAnimationIndex; + + // this is the actual duration of uncontrolled animations + // it helps seeking and even going forward + QList actualDuration; + + void restart(); + int lastLoop; + + // handle time changes + void rewindForwards(const AnimationIndex &newAnimationIndex); + void advanceForwards(const AnimationIndex &newAnimationIndex); + + // private slot + void _q_uncontrolledAnimationFinished(); +}; + +QT_END_NAMESPACE + +#endif //QSEQUENTIALANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp new file mode 100644 index 0000000..a6834bb --- /dev/null +++ b/src/corelib/animation/qvariantanimation.cpp @@ -0,0 +1,644 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_NO_ANIMATION + +#include "qvariantanimation.h" +#include "qvariantanimation_p.h" + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QVariantAnimation + \ingroup animation + \brief The QVariantAnimation class provides an abstract base class for animations. + \since 4.6 + + This class is part of \l{The Animation Framework}. It serves as a + base class for property and item animations, with functions for + shared functionality. + + QVariantAnimation cannot be used directly as it is an abstract + class; it does not implement + \l{QAbstractAnimation::}{updateCurrentValue()} from + QAbstractAnimation. The class performs interpolation over + \l{QVariant}s, but leaves using the interpolated values to its + subclasses. Currently, Qt provides QPropertyAnimation, which + animates Qt \l{Qt's Property System}{properties}. See the + QPropertyAnimation class description if you wish to animate such + properties. + + You can then set start and end values for the property by calling + setStartValue() and setEndValue(), and finally call start() to + start the animation. QVariantAnimation will interpolate the + property of the target object and emit valueChanged(). To react to + a change in the current value you have to reimplement the + updateCurrentValue() virtual function. + + It is also possible to set values at specified steps situated + between the start and end value. The interpolation will then + touch these points at the specified steps. Note that the start and + end values are defined as the key values at 0.0 and 1.0. + + There are two ways to affect how QVariantAnimation interpolates + the values. You can set an easing curve by calling + setEasingCurve(), and configure the duration by calling + setDuration(). You can change how the QVariants are interpolated + by creating a subclass of QVariantAnimation, and reimplementing + the virtual interpolated() function. + + Subclassing QVariantAnimation can be an alternative if you have + \l{QVariant}s that you do not wish to declare as Qt properties. + Note, however, that you in most cases will be better off declaring + your QVariant as a property. + + Not all QVariant types are supported. Below is a list of currently + supported QVariant types: + + \list + \o \l{QMetaType::}{Int} + \o \l{QMetaType::}{Double} + \o \l{QMetaType::}{Float} + \o \l{QMetaType::}{QLine} + \o \l{QMetaType::}{QLineF} + \o \l{QMetaType::}{QPoint} + \o \l{QMetaType::}{QSize} + \o \l{QMetaType::}{QSizeF} + \o \l{QMetaType::}{QRect} + \o \l{QMetaType::}{QRectF} + \endlist + + If you need to interpolate other variant types, including custom + types, you have to implement interpolation for these yourself. + You do this by reimplementing interpolated(), which returns + interpolation values for the value being interpolated. + + \omit We need some snippets around here. \endomit + + \sa QPropertyAnimation, QAbstractAnimation, {The Animation Framework} +*/ + +/*! + \fn void QVariantAnimation::valueChanged(const QVariant &value) + + QVariantAnimation emits this signal whenever the current \a value changes. + + \sa currentValue, startValue, endValue +*/ + +static bool animationValueLessThan(const QVariantAnimation::KeyValue &p1, const QVariantAnimation::KeyValue &p2) +{ + return p1.first < p2.first; +} + +template<> Q_INLINE_TEMPLATE QRect _q_interpolate(const QRect &f, const QRect &t, qreal progress) +{ + QRect ret; + ret.setCoords(_q_interpolate(f.left(), t.left(), progress), + _q_interpolate(f.top(), t.top(), progress), + _q_interpolate(f.right(), t.right(), progress), + _q_interpolate(f.bottom(), t.bottom(), progress)); + return ret; +} + +template<> Q_INLINE_TEMPLATE QRectF _q_interpolate(const QRectF &f, const QRectF &t, qreal progress) +{ + qreal x1, y1, w1, h1; + f.getRect(&x1, &y1, &w1, &h1); + qreal x2, y2, w2, h2; + t.getRect(&x2, &y2, &w2, &h2); + return QRectF(_q_interpolate(x1, x2, progress), _q_interpolate(y1, y2, progress), + _q_interpolate(w1, w2, progress), _q_interpolate(h1, h2, progress)); +} + +template<> Q_INLINE_TEMPLATE QLine _q_interpolate(const QLine &f, const QLine &t, qreal progress) +{ + return QLine( _q_interpolate(f.p1(), t.p1(), progress), _q_interpolate(f.p2(), t.p2(), progress)); +} + +template<> Q_INLINE_TEMPLATE QLineF _q_interpolate(const QLineF &f, const QLineF &t, qreal progress) +{ + return QLineF( _q_interpolate(f.p1(), t.p1(), progress), _q_interpolate(f.p2(), t.p2(), progress)); +} + +void QVariantAnimationPrivate::convertValues(int t) +{ + //this ensures that all the keyValues are of type t + for (int i = 0; i < keyValues.count(); ++i) { + QVariantAnimation::KeyValue &pair = keyValues[i]; + if (pair.second.userType() != t) + pair.second.convert(static_cast(t)); + } + interpolator = 0; // if the type changed we need to update the interpolator +} + +/*! + \internal + The goal of this function is to update the currentInterval member. As a consequence, we also + need to update the currentValue. + Set \a force to true to always recalculate the interval. +*/ +void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/) +{ + // can't interpolate if we have only 1 key value + if (keyValues.count() <= 1) + return; + + const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration))); + + if (force || progress < currentInterval.start.first || progress > currentInterval.end.first) { + //let's update currentInterval + QVariantAnimation::KeyValues::const_iterator itStart = qLowerBound(keyValues.constBegin(), + keyValues.constEnd(), + qMakePair(progress, QVariant()), + animationValueLessThan); + QVariantAnimation::KeyValues::const_iterator itEnd = itStart; + + // If we are at the end we should continue to use the last keyValues in case of extrapolation (progress > 1.0). + // This is because the easing function can return a value slightly outside the range [0, 1] + if (itStart != keyValues.constEnd()) { + // this can't happen because we always prepend the default start value there + if (itStart == keyValues.constBegin()) { + ++itEnd; + } else { + --itStart; + } + + // update all the values of the currentInterval + currentInterval.start = *itStart; + currentInterval.end = *itEnd; + } + } + setCurrentValueForProgress(progress); +} + +void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress) +{ + Q_Q(QVariantAnimation); + + const qreal startProgress = currentInterval.start.first; + const qreal endProgress = currentInterval.end.first; + const qreal localProgress = (progress - startProgress) / (endProgress - startProgress); + + QVariant ret = q->interpolated(currentInterval.start.second, + currentInterval.end.second, + localProgress); + qSwap(currentValue, ret); + q->updateCurrentValue(currentValue); + if ((connectedSignals & changedSignalMask) && currentValue != ret) { + //the value has changed + emit q->valueChanged(currentValue); + } +} + +QVariant QVariantAnimationPrivate::valueAt(qreal step) const +{ + QVariantAnimation::KeyValues::const_iterator result = + qBinaryFind(keyValues.begin(), keyValues.end(), qMakePair(step, QVariant()), animationValueLessThan); + if (result != keyValues.constEnd()) + return result->second; + + return QVariant(); +} + +void QVariantAnimationPrivate::setValueAt(qreal step, const QVariant &value) +{ + if (step < qreal(0.0) || step > qreal(1.0)) { + qWarning("QVariantAnimation::setValueAt: invalid step = %f", step); + return; + } + + QVariantAnimation::KeyValue pair(step, value); + + QVariantAnimation::KeyValues::iterator result = qLowerBound(keyValues.begin(), keyValues.end(), pair, animationValueLessThan); + if (result == keyValues.end() || result->first != step) { + keyValues.insert(result, pair); + } else { + if (value.isValid()) + result->second = value; // replaces the previous value + else if (step == 0 && !hasStartValue && defaultStartValue.isValid()) + result->second = defaultStartValue; // resets to the default start value + else + keyValues.erase(result); // removes the previous value + } + + recalculateCurrentInterval(/*force=*/true); +} + +void QVariantAnimationPrivate::setDefaultStartValue(const QVariant &value) +{ + defaultStartValue = value; + if (!hasStartValue) + setValueAt(0, value); +} + +/*! + Construct a QVariantAnimation object. \a parent is passed to QAbstractAnimation's + constructor. +*/ +QVariantAnimation::QVariantAnimation(QObject *parent) : QAbstractAnimation(*new QVariantAnimationPrivate, parent) +{ + d_func()->init(); +} + +/*! + \internal +*/ +QVariantAnimation::QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent) : QAbstractAnimation(dd, parent) +{ + d_func()->init(); +} + +/*! + Destroys the animation. +*/ +QVariantAnimation::~QVariantAnimation() +{ +} + +/*! + \property QVariantAnimation::easingCurve + \brief the easing curve of the animation + + This property defines the easing curve of the animation. By + default, a linear easing curve is used, resulting in linear + interpolation. Other curves are provided, for instance, + QEasingCurve::InCirc, which provides a circular entry curve. + Another example is QEasingCurve::InOutElastic, which provides an + elastic effect on the values of the interpolated variant. + + The easing curve is used with the interpolator, the interpolated() + virtual function, the animation's duration, and iterationCount, to + control how the current value changes as the animation progresses. +*/ +QEasingCurve QVariantAnimation::easingCurve() const +{ + Q_D(const QVariantAnimation); + return d->easing; +} + +void QVariantAnimation::setEasingCurve(const QEasingCurve &easing) +{ + Q_D(QVariantAnimation); + d->easing = easing; + d->recalculateCurrentInterval(); +} + +Q_GLOBAL_STATIC(QVector, registeredInterpolators) +Q_GLOBAL_STATIC(QReadWriteLock, registeredInterpolatorsLock) + +/*! + \fn void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) + \relates QVariantAnimation + \threadsafe + + Registers a custom interpolator \a func for the template type \c{T}. + The interpolator has to be registered before the animation is constructed. + To unregister (and use the default interpolator) set \a func to 0. + */ + +/*! + \internal + \typedef QVariantAnimation::Interpolator + + This is a typedef for a pointer to a function with the following + signature: + \code + QVariant myInterpolator(const QVariant &from, const QVariant &to, qreal progress); + \endcode + +*/ + +/*! \internal + * Registers a custom interpolator \a func for the specific \a interpolationType. + * The interpolator has to be registered before the animation is constructed. + * To unregister (and use the default interpolator) set \a func to 0. + */ +void QVariantAnimation::registerInterpolator(QVariantAnimation::Interpolator func, int interpolationType) +{ + // will override any existing interpolators + QWriteLocker locker(registeredInterpolatorsLock()); + if (int(interpolationType) >= registeredInterpolators()->count()) + registeredInterpolators()->resize(int(interpolationType) + 1); + registeredInterpolators()->replace(interpolationType, func); +} + + +template static inline QVariantAnimation::Interpolator castToInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) +{ + return reinterpret_cast(func); +} + +QVariantAnimation::Interpolator QVariantAnimationPrivate::getInterpolator(int interpolationType) +{ + QReadLocker locker(registeredInterpolatorsLock()); + QVariantAnimation::Interpolator ret = 0; + if (interpolationType < registeredInterpolators()->count()) { + ret = registeredInterpolators()->at(interpolationType); + if (ret) return ret; + } + + switch(interpolationType) + { + case QMetaType::Int: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::Double: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::Float: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::QLine: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::QLineF: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::QPoint: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::QPointF: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::QSize: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::QSizeF: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::QRect: + return castToInterpolator(_q_interpolateVariant); + case QMetaType::QRectF: + return castToInterpolator(_q_interpolateVariant); + default: + return 0; //this type is not handled + } +} + +/*! + \property QVariantAnimation::duration + \brief the duration of the animation + + This property describes the duration in milliseconds of the + animation. The default duration is 250 milliseconds. + + \sa QAbstractAnimation::duration() + */ +int QVariantAnimation::duration() const +{ + Q_D(const QVariantAnimation); + return d->duration; +} + +void QVariantAnimation::setDuration(int msecs) +{ + Q_D(QVariantAnimation); + if (msecs < 0) { + qWarning("QVariantAnimation::setDuration: cannot set a negative duration"); + return; + } + if (d->duration == msecs) + return; + d->duration = msecs; + d->recalculateCurrentInterval(); +} + +/*! + \property QVariantAnimation::startValue + \brief the optional start value of the animation + + This property describes the optional start value of the animation. If + omitted, or if a null QVariant is assigned as the start value, the + animation will use the current position of the end when the animation + is started. + + \sa endValue +*/ +QVariant QVariantAnimation::startValue() const +{ + return keyValueAt(0); +} + +void QVariantAnimation::setStartValue(const QVariant &value) +{ + setKeyValueAt(0, value); +} + +/*! + \property QVariantAnimation::endValue + \brief the end value of the animation + + This property describes the end value of the animation. + + \sa startValue + */ +QVariant QVariantAnimation::endValue() const +{ + return keyValueAt(1); +} + +void QVariantAnimation::setEndValue(const QVariant &value) +{ + setKeyValueAt(1, value); +} + + +/*! + Returns the key frame value for the given \a step. The given \a step + must be in the range 0 to 1. If there is no KeyValue for \a step, + it returns an invalid QVariant. + + \sa keyValues(), setKeyValueAt() +*/ +QVariant QVariantAnimation::keyValueAt(qreal step) const +{ + Q_D(const QVariantAnimation); + if (step == 0 && !d->hasStartValue) + return QVariant(); //special case where we don't have an explicit startValue + + return d->valueAt(step); +} + +/*! + \typedef QVariantAnimation::KeyValue + + This is a typedef for QPair. +*/ +/*! + \typedef QVariantAnimation::KeyValues + + This is a typedef for QVector +*/ + +/*! + Creates a key frame at the given \a step with the given \a value. + The given \a step must be in the range 0 to 1. + + \sa setKeyValues(), keyValueAt() +*/ +void QVariantAnimation::setKeyValueAt(qreal step, const QVariant &value) +{ + Q_D(QVariantAnimation); + if (step == 0) + d->hasStartValue = value.isValid(); + d->setValueAt(step, value); +} + +/*! + Returns the key frames of this animation. + + \sa keyValueAt(), setKeyValues() +*/ +QVariantAnimation::KeyValues QVariantAnimation::keyValues() const +{ + Q_D(const QVariantAnimation); + QVariantAnimation::KeyValues ret = d->keyValues; + //in case we added the default start value, we remove it + if (!d->hasStartValue && !ret.isEmpty() && ret.at(0).first == 0) + ret.remove(0); + return ret; +} + +/*! + Replaces the current set of key frames with the given \a keyValues. + the step of the key frames must be in the range 0 to 1. + + \sa keyValues(), keyValueAt() +*/ +void QVariantAnimation::setKeyValues(const KeyValues &keyValues) +{ + Q_D(QVariantAnimation); + d->keyValues = keyValues; + qSort(d->keyValues.begin(), d->keyValues.end(), animationValueLessThan); + d->hasStartValue = !d->keyValues.isEmpty() && d->keyValues.at(0).first == 0; + d->recalculateCurrentInterval(/*force=*/true); +} + +/*! + \property QVariantAnimation::currentValue + \brief the current value of the animation. + + This property describes the current value; an interpolated value + between the \l{startValue}{start value} and the \l{endValue}{end + value}, using the current time for progress. The value itself is + obtained from interpolated(), which is called repeatedly as the + animation is running. + + QVariantAnimation calls the virtual updateCurrentValue() function + when the current value changes. This is particularly useful for + subclasses that need to track updates. For example, + QPropertyAnimation uses this function to animate Qt \l{Qt's + Property System}{properties}. + + \sa startValue, endValue +*/ +QVariant QVariantAnimation::currentValue() const +{ + Q_D(const QVariantAnimation); + if (!d->currentValue.isValid()) + const_cast(d)->recalculateCurrentInterval(); + return d->currentValue; +} + +/*! + \reimp + */ +bool QVariantAnimation::event(QEvent *event) +{ + return QAbstractAnimation::event(event); +} + +/*! + \reimp +*/ +void QVariantAnimation::updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) +{ + Q_UNUSED(oldState); + Q_UNUSED(newState); +} + +/*! + + This virtual function returns the linear interpolation between + variants \a from and \a to, at \a progress, usually a value + between 0 and 1. You can reimplement this function in a subclass + of QVariantAnimation to provide your own interpolation algorithm. + + Note that in order for the interpolation to work with a + QEasingCurve that return a value smaller than 0 or larger than 1 + (such as QEasingCurve::InBack) you should make sure that it can + extrapolate. If the semantic of the datatype does not allow + extrapolation this function should handle that gracefully. + + You should call the QVariantAnimation implementation of this + function if you want your class to handle the types already + supported by Qt (see class QVariantAnimation description for a + list of supported types). + + \sa QEasingCurve + */ +QVariant QVariantAnimation::interpolated(const QVariant &from, const QVariant &to, qreal progress) const +{ + Q_D(const QVariantAnimation); + if (d->interpolator == 0) { + if (from.userType() == to.userType()) + d->interpolator = QVariantAnimationPrivate::getInterpolator(from.userType()); + if (d->interpolator == 0) //no interpolator found + return QVariant(); + } + + return d->interpolator(from.constData(), to.constData(), progress); +} + +/*! + \reimp + */ +void QVariantAnimation::updateCurrentTime(int msecs) +{ + Q_D(QVariantAnimation); + Q_UNUSED(msecs); + d->recalculateCurrentInterval(); +} + +QT_END_NAMESPACE + +#include "moc_qvariantanimation.cpp" + +#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h new file mode 100644 index 0000000..5b90930 --- /dev/null +++ b/src/corelib/animation/qvariantanimation.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANIMATION_H +#define QANIMATION_H + +#include +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +#ifndef QT_NO_ANIMATION + +class QVariantAnimationPrivate; +class Q_CORE_EXPORT QVariantAnimation : public QAbstractAnimation +{ + Q_OBJECT + Q_PROPERTY(QVariant startValue READ startValue WRITE setStartValue) + Q_PROPERTY(QVariant endValue READ endValue WRITE setEndValue) + Q_PROPERTY(QVariant currentValue READ currentValue NOTIFY currentValueChanged) + Q_PROPERTY(int duration READ duration WRITE setDuration) + Q_PROPERTY(QEasingCurve easingCurve READ easingCurve WRITE setEasingCurve) + +public: + typedef QPair KeyValue; + typedef QVector KeyValues; + + QVariantAnimation(QObject *parent = 0); + ~QVariantAnimation(); + + QVariant startValue() const; + void setStartValue(const QVariant &value); + + QVariant endValue() const; + void setEndValue(const QVariant &value); + + QVariant keyValueAt(qreal step) const; + void setKeyValueAt(qreal step, const QVariant &value); + + KeyValues keyValues() const; + void setKeyValues(const KeyValues &values); + + QVariant currentValue() const; + + int duration() const; + void setDuration(int msecs); + + QEasingCurve easingCurve() const; + void setEasingCurve(const QEasingCurve &easing); + + typedef QVariant (*Interpolator)(const void *from, const void *to, qreal progress); + +Q_SIGNALS: + void valueChanged(const QVariant &value); + +protected: + QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent = 0); + bool event(QEvent *event); + + void updateCurrentTime(int msecs); + void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); + + virtual void updateCurrentValue(const QVariant &value) = 0; + virtual QVariant interpolated(const QVariant &from, const QVariant &to, qreal progress) const; + +private: + template friend void qRegisterAnimationInterpolator(QVariant (*func)(const T &, const T &, qreal)); + static void registerInterpolator(Interpolator func, int interpolationType); + + Q_DISABLE_COPY(QVariantAnimation) + Q_DECLARE_PRIVATE(QVariantAnimation) +}; + +template +static void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) { + QVariantAnimation::registerInterpolator(reinterpret_cast(func), qMetaTypeId()); +} + +#endif //QT_NO_ANIMATION + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //QANIMATION_H diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h new file mode 100644 index 0000000..0d296db --- /dev/null +++ b/src/corelib/animation/qvariantanimation_p.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANIMATION_P_H +#define QANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of QIODevice. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qvariantanimation.h" +#include +#include +#include + +#include "qabstractanimation_p.h" + +QT_BEGIN_NAMESPACE + +class QVariantAnimationPrivate : public QAbstractAnimationPrivate +{ + Q_DECLARE_PUBLIC(QVariantAnimation) +public: + + QVariantAnimationPrivate() : duration(250), hasStartValue(false) + { + } + + void init() + { + //we keep the mask so that we emit valueChanged only when needed (for performance reasons) + changedSignalMask = (1 << q_func()->metaObject()->indexOfSignal("valueChanged(QVariant)")); + currentInterval.start.first = currentInterval.end.first = 2; //will force the initial refresh + interpolator = 0; + } + + static QVariantAnimationPrivate *get(QVariantAnimation *q) + { + return q->d_func(); + } + + void setDefaultStartValue(const QVariant &value); + + int duration; + QEasingCurve easing; + + QVariantAnimation::KeyValues keyValues; + QVariant currentValue; + QVariant defaultStartValue; + bool hasStartValue; + + //this is used to keep track of the KeyValue interval in which we currently are + struct + { + QVariantAnimation::KeyValue start, end; + } currentInterval; + + mutable QVariantAnimation::Interpolator interpolator; + + quint32 changedSignalMask; + + void setCurrentValueForProgress(const qreal progress); + void recalculateCurrentInterval(bool force=false); + void setValueAt(qreal, const QVariant &); + QVariant valueAt(qreal step) const; + void convertValues(int t); + + static QVariantAnimation::Interpolator getInterpolator(int interpolationType); +}; + +//this should make the interpolation faster +template inline T _q_interpolate(const T &f, const T &t, qreal progress) +{ + return T(f + (t - f) * progress); +} + +template inline QVariant _q_interpolateVariant(const T &from, const T &to, qreal progress) +{ + return _q_interpolate(from, to, progress); +} + + +QT_END_NAMESPACE + +#endif //QANIMATION_P_H diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index f99d57f..db51d43 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -5,6 +5,7 @@ DEFINES += QT_BUILD_CORE_LIB QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000 include(../qbase.pri) +include(animation/animation.pri) include(arch/arch.pri) include(concurrent/concurrent.pri) include(global/global.pri) @@ -14,6 +15,7 @@ include(io/io.pri) include(plugin/plugin.pri) include(kernel/kernel.pri) include(codecs/codecs.pri) +include(statemachine/statemachine.pri) include(xml/xml.pri) mac|darwin:LIBS += -framework ApplicationServices diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 68649a6..ecef555 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -12,7 +12,7 @@ HEADERS += \ kernel/qcoreevent.h \ kernel/qmetaobject.h \ kernel/qmetatype.h \ - kernel/qmimedata.h \ + kernel/qmimedata.h \ kernel/qobject.h \ kernel/qobjectdefs.h \ kernel/qsignalmapper.h \ @@ -27,8 +27,8 @@ HEADERS += \ kernel/qvariant_p.h \ kernel/qmetaobject_p.h \ kernel/qobject_p.h \ - kernel/qcoreglobaldata_p.h \ - kernel/qsharedmemory.h \ + kernel/qcoreglobaldata_p.h \ + kernel/qsharedmemory.h \ kernel/qsharedmemory_p.h \ kernel/qsystemsemaphore.h \ kernel/qsystemsemaphore_p.h \ @@ -43,7 +43,7 @@ SOURCES += \ kernel/qcoreevent.cpp \ kernel/qmetaobject.cpp \ kernel/qmetatype.cpp \ - kernel/qmimedata.cpp \ + kernel/qmimedata.cpp \ kernel/qobject.cpp \ kernel/qobjectcleanuphandler.cpp \ kernel/qsignalmapper.cpp \ diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 11a2d3c..d6b0174 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -264,6 +264,8 @@ QT_BEGIN_NAMESPACE \omitvalue NetworkReplyUpdated \omitvalue FutureCallOut \omitvalue CocoaRequestModal + \omitvalue Wrapped + \omitvalue Signal */ /*! diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index fa472e6..18188a8 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_HEADER @@ -54,7 +55,9 @@ QT_MODULE(Core) class QEventPrivate; class Q_CORE_EXPORT QEvent // event base class { + Q_GADGET QDOC_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) + Q_ENUMS(Type) public: enum Type { /* @@ -266,7 +269,10 @@ public: CocoaRequestModal = 190, // Internal for requesting an application modal Cocoa Window MacGLClearDrawable = 191, // Internal Cocoa, the window has changed, so we must clear - // 512 reserved for Qt Jambi's MetaCall event + Signal = 192, + Wrapped = 193, + + // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event User = 1000, // first user event id diff --git a/src/corelib/statemachine/qabstractstate.cpp b/src/corelib/statemachine/qabstractstate.cpp new file mode 100644 index 0000000..942722f --- /dev/null +++ b/src/corelib/statemachine/qabstractstate.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractstate.h" +#include "qabstractstate_p.h" +#include "qstate.h" +#include "qstate_p.h" +#include "qstatemachine.h" +#include "qstatemachine_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QAbstractState + + \brief The QAbstractState class is the base class of states of a QStateMachine. + + \since 4.6 + \ingroup statemachine + + The QAbstractState class is the abstract base class of states that are part + of a QStateMachine. It defines the interface that all state objects have in + common. QAbstractState is part of \l{The State Machine Framework}. + + The entered() signal is emitted when the state has been entered. The + exited() signal is emitted when the state has been exited. + + The parentState() function returns the state's parent state. The machine() + function returns the state machine that the state is part of. + + \section1 Subclassing + + The onEntry() function is called when the state is entered; reimplement this + function to perform custom processing when the state is entered. + + The onExit() function is called when the state is exited; reimplement this + function to perform custom processing when the state is exited. +*/ + +QAbstractStatePrivate::QAbstractStatePrivate() +{ +} + +QAbstractStatePrivate *QAbstractStatePrivate::get(QAbstractState *q) +{ + return q->d_func(); +} + +QStateMachine *QAbstractStatePrivate::machine() const +{ + Q_Q(const QAbstractState); + QObject *par = q->parent(); + while (par != 0) { + if (QStateMachine *mach = qobject_cast(par)) + return mach; + par = par->parent(); + } + return 0; +} + +void QAbstractStatePrivate::callOnEntry(QEvent *e) +{ + Q_Q(QAbstractState); + q->onEntry(e); +} + +void QAbstractStatePrivate::callOnExit(QEvent *e) +{ + Q_Q(QAbstractState); + q->onExit(e); +} + +void QAbstractStatePrivate::emitEntered() +{ + Q_Q(QAbstractState); + emit q->entered(); +} + +void QAbstractStatePrivate::emitExited() +{ + Q_Q(QAbstractState); + emit q->exited(); +} + +/*! + Constructs a new state with the given \a parent state. +*/ +QAbstractState::QAbstractState(QState *parent) + : QObject(*new QAbstractStatePrivate, parent) +{ +} + +/*! + \internal +*/ +QAbstractState::QAbstractState(QAbstractStatePrivate &dd, QState *parent) + : QObject(dd, parent) +{ +} + +/*! + Destroys this state. +*/ +QAbstractState::~QAbstractState() +{ +} + +/*! + Returns this state's parent state, or 0 if the state has no parent state. +*/ +QState *QAbstractState::parentState() const +{ + return qobject_cast(parent()); +} + +/*! + Returns the state machine that this state is part of, or 0 if the state is + not part of a state machine. +*/ +QStateMachine *QAbstractState::machine() const +{ + Q_D(const QAbstractState); + return d->machine(); +} + +/*! + \fn QAbstractState::onExit(QEvent *event) + + This function is called when the state is exited. The given \a event is what + caused the state to be exited. Reimplement this function to perform custom + processing when the state is exited. +*/ + +/*! + \fn QAbstractState::onEntry(QEvent *event) + + This function is called when the state is entered. The given \a event is + what caused the state to be entered. Reimplement this function to perform + custom processing when the state is entered. +*/ + +/*! + \fn QAbstractState::entered() + + This signal is emitted when the state has been entered (after onEntry() has + been called). +*/ + +/*! + \fn QAbstractState::exited() + + This signal is emitted when the state has been exited (after onExit() has + been called). +*/ + +/*! + \reimp +*/ +bool QAbstractState::event(QEvent *e) +{ + return QObject::event(e); +} + +QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qabstractstate.h b/src/corelib/statemachine/qabstractstate.h new file mode 100644 index 0000000..d0ebb52 --- /dev/null +++ b/src/corelib/statemachine/qabstractstate.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTSTATE_H +#define QABSTRACTSTATE_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QState; +class QStateMachine; + +class QAbstractStatePrivate; +class Q_CORE_EXPORT QAbstractState : public QObject +{ + Q_OBJECT +public: + ~QAbstractState(); + + QState *parentState() const; + QStateMachine *machine() const; + +Q_SIGNALS: + void entered(); + void exited(); + +protected: + QAbstractState(QState *parent = 0); + + virtual void onEntry(QEvent *event) = 0; + virtual void onExit(QEvent *event) = 0; + + bool event(QEvent *e); + +protected: + QAbstractState(QAbstractStatePrivate &dd, QState *parent); + +private: + Q_DISABLE_COPY(QAbstractState) + Q_DECLARE_PRIVATE(QAbstractState) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/qabstractstate_p.h b/src/corelib/statemachine/qabstractstate_p.h new file mode 100644 index 0000000..2aad47e --- /dev/null +++ b/src/corelib/statemachine/qabstractstate_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTSTATE_P_H +#define QABSTRACTSTATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QStateMachine; + +class QAbstractState; +class Q_CORE_EXPORT QAbstractStatePrivate + : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QAbstractState) + +public: + QAbstractStatePrivate(); + + static QAbstractStatePrivate *get(QAbstractState *q); + + QStateMachine *machine() const; + + void callOnEntry(QEvent *e); + void callOnExit(QEvent *e); + + void emitEntered(); + void emitExited(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp new file mode 100644 index 0000000..dfcafeb --- /dev/null +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -0,0 +1,342 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstracttransition.h" +#include "qabstracttransition_p.h" +#include "qabstractstate.h" +#include "qstate.h" +#include "qstatemachine.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QAbstractTransition + + \brief The QAbstractTransition class is the base class of transitions between QAbstractState objects. + + \since 4.6 + \ingroup statemachine + + The QAbstractTransition class is the abstract base class of transitions + between states (QAbstractState objects) of a + QStateMachine. QAbstractTransition is part of \l{The State Machine + Framework}. + + The sourceState() function returns the source of the transition. The + targetStates() function returns the targets of the transition. The machine() + function returns the state machine that the transition is part of. + + Transitions can cause animations to be played. Use the addAnimation() + function to add an animation to the transition. + + \section1 Subclassing + + The eventTest() function is called by the state machine to determine whether + an event should trigger the transition. In your reimplementation you + typically check the event type and cast the event object to the proper type, + and check that one or more properties of the event meet your criteria. + + The onTransition() function is called when the transition is triggered; + reimplement this function to perform custom processing for the transition. +*/ + +/*! + \property QAbstractTransition::sourceState + + \brief the source state (parent) of this transition +*/ + +/*! + \property QAbstractTransition::targetState + + \brief the target state of this transition +*/ + +/*! + \property QAbstractTransition::targetStates + + \brief the target states of this transition + + If multiple states are specified, all must be descendants of the same + parallel group state. +*/ + +QAbstractTransitionPrivate::QAbstractTransitionPrivate() +{ +} + +QAbstractTransitionPrivate *QAbstractTransitionPrivate::get(QAbstractTransition *q) +{ + return q->d_func(); +} + +QStateMachine *QAbstractTransitionPrivate::machine() const +{ + Q_Q(const QAbstractTransition); + QObject *par = q->parent(); + while (par != 0) { + if (QStateMachine *mach = qobject_cast(par)) + return mach; + par = par->parent(); + } + return 0; +} + +bool QAbstractTransitionPrivate::callEventTest(QEvent *e) +{ + Q_Q(QAbstractTransition); + return q->eventTest(e); +} + +void QAbstractTransitionPrivate::callOnTransition(QEvent *e) +{ + Q_Q(QAbstractTransition); + q->onTransition(e); +} + +QState *QAbstractTransitionPrivate::sourceState() const +{ + Q_Q(const QAbstractTransition); + return qobject_cast(q->parent()); +} + +/*! + Constructs a new QAbstractTransition object with the given \a sourceState. +*/ +QAbstractTransition::QAbstractTransition(QState *sourceState) + : QObject(*new QAbstractTransitionPrivate, sourceState) +{ +} + +/*! + Constructs a new QAbstractTransition object with the given \a targets and \a + sourceState. +*/ +QAbstractTransition::QAbstractTransition(const QList &targets, + QState *sourceState) + : QObject(*new QAbstractTransitionPrivate, sourceState) +{ + setTargetStates(targets); +} + +/*! + \internal +*/ +QAbstractTransition::QAbstractTransition(QAbstractTransitionPrivate &dd, + QState *parent) + : QObject(dd, parent) +{ +} + +/*! + \internal +*/ +QAbstractTransition::QAbstractTransition(QAbstractTransitionPrivate &dd, + const QList &targets, + QState *parent) + : QObject(dd, parent) +{ + setTargetStates(targets); +} + +/*! + Destroys this transition. +*/ +QAbstractTransition::~QAbstractTransition() +{ +} + +/*! + Returns the source state of this transition, or 0 if this transition has no + source state. +*/ +QState *QAbstractTransition::sourceState() const +{ + Q_D(const QAbstractTransition); + return d->sourceState(); +} + +/*! + Returns the target state of this transition, or 0 if the transition has no + target. +*/ +QAbstractState *QAbstractTransition::targetState() const +{ + Q_D(const QAbstractTransition); + if (d->targetStates.isEmpty()) + return 0; + return d->targetStates.first(); +} + +/*! + Sets the \a target state of this transition. +*/ +void QAbstractTransition::setTargetState(QAbstractState* target) +{ + Q_D(QAbstractTransition); + if (!target) + d->targetStates.clear(); + else + setTargetStates(QList() << target); +} + +/*! + Returns the target states of this transition, or an empty list if this + transition has no target states. +*/ +QList QAbstractTransition::targetStates() const +{ + Q_D(const QAbstractTransition); + QList result; + for (int i = 0; i < d->targetStates.size(); ++i) { + QAbstractState *target = d->targetStates.at(i); + if (target) + result.append(target); + } + return result; +} + +/*! + Sets the target states of this transition to be the given \a targets. +*/ +void QAbstractTransition::setTargetStates(const QList &targets) +{ + Q_D(QAbstractTransition); + + for (int i=0; imachine() != 0 && target->machine()->rootState() == target) { + qWarning("QAbstractTransition::setTargetStates: root state cannot be target of transition"); + return; + } + } + + d->targetStates.clear(); + for (int i = 0; i < targets.size(); ++i) + d->targetStates.append(targets.at(i)); +} + +/*! + Returns the state machine that this transition is part of, or 0 if the + transition is not part of a state machine. +*/ +QStateMachine *QAbstractTransition::machine() const +{ + Q_D(const QAbstractTransition); + return d->machine(); +} + +#ifndef QT_NO_ANIMATION + +/*! + Adds the given \a animation to this transition. + The transition does not take ownership of the animation. + + \sa removeAnimation(), animations() +*/ +void QAbstractTransition::addAnimation(QAbstractAnimation *animation) +{ + Q_D(QAbstractTransition); + if (!animation) { + qWarning("QAbstractTransition::addAnimation: cannot add null animation"); + return; + } + d->animations.append(animation); +} + +/*! + Removes the given \a animation from this transition. + + \sa addAnimation() +*/ +void QAbstractTransition::removeAnimation(QAbstractAnimation *animation) +{ + Q_D(QAbstractTransition); + if (!animation) { + qWarning("QAbstractTransition::removeAnimation: cannot remove null animation"); + return; + } + d->animations.removeOne(animation); +} + +/*! + Returns the list of animations associated with this transition, or an empty + list if it has no animations. + + \sa addAnimation() +*/ +QList QAbstractTransition::animations() const +{ + Q_D(const QAbstractTransition); + return d->animations; +} + +#endif + +/*! + \fn QAbstractTransition::eventTest(QEvent *event) + + This function is called to determine whether the given \a event should cause + this transition to trigger. Reimplement this function and return true if the + event should trigger the transition, otherwise return false. +*/ + +/*! + \fn QAbstractTransition::onTransition(QEvent *event) + + This function is called when the transition is triggered. The given \a event + is what caused the transition to trigger. Reimplement this function to + perform custom processing when the transition is triggered. +*/ + +/*! + \reimp +*/ +bool QAbstractTransition::event(QEvent *e) +{ + return QObject::event(e); +} + +QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qabstracttransition.h b/src/corelib/statemachine/qabstracttransition.h new file mode 100644 index 0000000..c63d55a --- /dev/null +++ b/src/corelib/statemachine/qabstracttransition.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTTRANSITION_H +#define QABSTRACTTRANSITION_H + +#include + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QEvent; +class QAbstractState; +class QState; +class QStateMachine; + +#ifndef QT_NO_ANIMATION +class QAbstractAnimation; +#endif + +class QAbstractTransitionPrivate; +class Q_CORE_EXPORT QAbstractTransition : public QObject +{ + Q_OBJECT + Q_PROPERTY(QState* sourceState READ sourceState) + Q_PROPERTY(QAbstractState* targetState READ targetState WRITE setTargetState) + Q_PROPERTY(QList targetStates READ targetStates WRITE setTargetStates) +public: + QAbstractTransition(QState *sourceState = 0); + QAbstractTransition(const QList &targets, QState *sourceState = 0); + virtual ~QAbstractTransition(); + + QState *sourceState() const; + QAbstractState *targetState() const; + void setTargetState(QAbstractState* target); + QList targetStates() const; + void setTargetStates(const QList &targets); + + QStateMachine *machine() const; + +#ifndef QT_NO_ANIMATION + void addAnimation(QAbstractAnimation *animation); + void removeAnimation(QAbstractAnimation *animation); + QList animations() const; +#endif + +protected: + virtual bool eventTest(QEvent *event) = 0; + + virtual void onTransition(QEvent *event) = 0; + + bool event(QEvent *e); + +protected: + QAbstractTransition(QAbstractTransitionPrivate &dd, QState *parent); + QAbstractTransition(QAbstractTransitionPrivate &dd, + const QList &targets, QState *parent); + +private: + Q_DISABLE_COPY(QAbstractTransition) + Q_DECLARE_PRIVATE(QAbstractTransition) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h new file mode 100644 index 0000000..f067984 --- /dev/null +++ b/src/corelib/statemachine/qabstracttransition_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTTRANSITION_P_H +#define QABSTRACTTRANSITION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QAbstractState; +class QState; +class QStateMachine; + +class QAbstractTransition; +class Q_CORE_EXPORT QAbstractTransitionPrivate + : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QAbstractTransition) +public: + QAbstractTransitionPrivate(); + + static QAbstractTransitionPrivate *get(QAbstractTransition *q); + + bool callEventTest(QEvent *e); + void callOnTransition(QEvent *e); + QState *sourceState() const; + QStateMachine *machine() const; + + QList > targetStates; + +#ifndef QT_NO_ANIMATION + QList animations; +#endif +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/statemachine/qeventtransition.cpp b/src/corelib/statemachine/qeventtransition.cpp new file mode 100644 index 0000000..74eb577 --- /dev/null +++ b/src/corelib/statemachine/qeventtransition.cpp @@ -0,0 +1,282 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeventtransition.h" +#include "qeventtransition_p.h" +#include "qwrappedevent.h" +#include "qstate.h" +#include "qstate_p.h" +#include "qstatemachine.h" +#include "qstatemachine_p.h" +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QEventTransition + + \brief The QEventTransition class provides a QObject-specific transition for Qt events. + + \since 4.6 + \ingroup statemachine + + A QEventTransition object binds an event to a particular QObject. + QEventTransition is part of \l{The State Machine Framework}. + + Example: + + \code + QPushButton *button = ...; + QState *s1 = ...; + QState *s2 = ...; + // If in s1 and the button receives an Enter event, transition to s2 + QEventTransition *enterTransition = new QEventTransition(button, QEvent::Enter); + enterTransition->setTargetState(s2); + s1->addTransition(enterTransition); + // If in s2 and the button receives an Exit event, transition back to s1 + QEventTransition *leaveTransition = new QEventTransition(button, QEvent::Leave); + leaveTransition->setTargetState(s1); + s2->addTransition(leaveTransition); + \endcode + + \section1 Subclassing + + When reimplementing the eventTest() function, you should first call the base + implementation to verify that the event is a QWrappedEvent for the proper + object and event type. You may then cast the event to a QWrappedEvent and + get the original event by calling QWrappedEvent::event(), and perform + additional checks on that object. + + \sa QState::addTransition() +*/ + +/*! + \property QEventTransition::eventObject + + \brief the event source that this event transition is associated with +*/ + +/*! + \property QEventTransition::eventType + + \brief the type of event that this event transition is associated with +*/ +QEventTransitionPrivate::QEventTransitionPrivate() +{ + object = 0; + eventType = QEvent::None; + registered = false; +} + +QEventTransitionPrivate *QEventTransitionPrivate::get(QEventTransition *q) +{ + return q->d_func(); +} + +void QEventTransitionPrivate::invalidate() +{ + Q_Q(QEventTransition); + if (registered) { + QState *source = sourceState(); + QStatePrivate *source_d = QStatePrivate::get(source); + QStateMachinePrivate *mach = QStateMachinePrivate::get(source_d->machine()); + if (mach) { + mach->unregisterEventTransition(q); + if (mach->configuration.contains(source)) + mach->registerEventTransition(q); + } + } +} + +/*! + Constructs a new QEventTransition object with the given \a sourceState. +*/ +QEventTransition::QEventTransition(QState *sourceState) + : QAbstractTransition(*new QEventTransitionPrivate, sourceState) +{ +} + +/*! + Constructs a new QEventTransition object associated with events of the given + \a type for the given \a object, and with the given \a sourceState. +*/ +QEventTransition::QEventTransition(QObject *object, QEvent::Type type, + QState *sourceState) + : QAbstractTransition(*new QEventTransitionPrivate, sourceState) +{ + Q_D(QEventTransition); + d->registered = false; + d->object = object; + d->eventType = type; +} + +/*! + Constructs a new QEventTransition object associated with events of the given + \a type for the given \a object. The transition has the given \a targets and + \a sourceState. +*/ +QEventTransition::QEventTransition(QObject *object, QEvent::Type type, + const QList &targets, + QState *sourceState) + : QAbstractTransition(*new QEventTransitionPrivate, targets, sourceState) +{ + Q_D(QEventTransition); + d->registered = false; + d->object = object; + d->eventType = type; +} + +/*! + \internal +*/ +QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QState *parent) + : QAbstractTransition(dd, parent) +{ +} + +/*! + \internal +*/ +QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object, + QEvent::Type type, QState *parent) + : QAbstractTransition(dd, parent) +{ + Q_D(QEventTransition); + d->registered = false; + d->object = object; + d->eventType = type; +} + +/*! + \internal +*/ +QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object, + QEvent::Type type, const QList &targets, + QState *parent) + : QAbstractTransition(dd, targets, parent) +{ + Q_D(QEventTransition); + d->registered = false; + d->object = object; + d->eventType = type; +} + +/*! + Destroys this QObject event transition. +*/ +QEventTransition::~QEventTransition() +{ +} + +/*! + Returns the event type that this event transition is associated with. +*/ +QEvent::Type QEventTransition::eventType() const +{ + Q_D(const QEventTransition); + return d->eventType; +} + +/*! + Sets the event \a type that this event transition is associated with. +*/ +void QEventTransition::setEventType(QEvent::Type type) +{ + Q_D(QEventTransition); + if (d->eventType == type) + return; + d->eventType = type; + d->invalidate(); +} + +/*! + Returns the event source associated with this event transition. +*/ +QObject *QEventTransition::eventObject() const +{ + Q_D(const QEventTransition); + return d->object; +} + +/*! + Sets the event source associated with this event transition to be the given + \a object. +*/ +void QEventTransition::setEventObject(QObject *object) +{ + Q_D(QEventTransition); + if (d->object == object) + return; + d->object = object; + d->invalidate(); +} + +/*! + \reimp +*/ +bool QEventTransition::eventTest(QEvent *event) +{ + Q_D(const QEventTransition); + if (event->type() == QEvent::Wrapped) { + QWrappedEvent *we = static_cast(event); + return (we->object() == d->object) + && (we->event()->type() == d->eventType); + } + return false; +} + +/*! + \reimp +*/ +void QEventTransition::onTransition(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \reimp +*/ +bool QEventTransition::event(QEvent *e) +{ + return QAbstractTransition::event(e); +} + +QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qeventtransition.h b/src/corelib/statemachine/qeventtransition.h new file mode 100644 index 0000000..3530bdd --- /dev/null +++ b/src/corelib/statemachine/qeventtransition.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVENTTRANSITION_H +#define QEVENTTRANSITION_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QEventTransitionPrivate; +class Q_CORE_EXPORT QEventTransition : public QAbstractTransition +{ + Q_OBJECT + Q_PROPERTY(QObject* eventObject READ eventObject WRITE setEventObject) + Q_PROPERTY(QEvent::Type eventType READ eventType WRITE setEventType) +public: + QEventTransition(QState *sourceState = 0); + QEventTransition(QObject *object, QEvent::Type type, QState *sourceState = 0); + QEventTransition(QObject *object, QEvent::Type type, + const QList &targets, QState *sourceState = 0); + ~QEventTransition(); + + QObject *eventObject() const; + void setEventObject(QObject *object); + + QEvent::Type eventType() const; + void setEventType(QEvent::Type type); + +protected: + bool eventTest(QEvent *event); + void onTransition(QEvent *event); + + bool event(QEvent *e); + +protected: + QEventTransition(QEventTransitionPrivate &dd, QState *parent); + QEventTransition(QEventTransitionPrivate &dd, QObject *object, + QEvent::Type type, QState *parent); + QEventTransition(QEventTransitionPrivate &dd, QObject *object, + QEvent::Type type, const QList &targets, + QState *parent); + +private: + Q_DISABLE_COPY(QEventTransition) + Q_DECLARE_PRIVATE(QEventTransition) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/qeventtransition_p.h b/src/corelib/statemachine/qeventtransition_p.h new file mode 100644 index 0000000..fca8c0d --- /dev/null +++ b/src/corelib/statemachine/qeventtransition_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEVENTTRANSITION_P_H +#define QEVENTTRANSITION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qabstracttransition_p.h" + +QT_BEGIN_NAMESPACE + +class QEventTransition; +class Q_CORE_EXPORT QEventTransitionPrivate : public QAbstractTransitionPrivate +{ + Q_DECLARE_PUBLIC(QEventTransition) +public: + QEventTransitionPrivate(); + + static QEventTransitionPrivate *get(QEventTransition *q); + + void invalidate(); + + bool registered; + QObject *object; + QEvent::Type eventType; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/statemachine/qfinalstate.cpp b/src/corelib/statemachine/qfinalstate.cpp new file mode 100644 index 0000000..0980336 --- /dev/null +++ b/src/corelib/statemachine/qfinalstate.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfinalstate.h" +#include "qabstractstate_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QFinalState + + \brief The QFinalState class provides a final state. + + \since 4.6 + \ingroup statemachine + + A final state is used to communicate that (part of) a QStateMachine has + finished its work. When a final top-level state is entered, the state + machine's \l{QStateMachine::finished()}{finished}() signal is emitted. In + general, when a final substate (a child of a QState) is entered, the parent + state's \l{QState::finished()}{finished}() signal is emitted. QFinalState + is part of \l{The State Machine Framework}. + + To use a final state, you create a QFinalState object and add a transition + to it from another state. Example: + + \code + QPushButton button; + + QStateMachine machine; + QState *s1 = new QState(); + QFinalState *s2 = new QFinalState(); + s1->addTransition(&button, SIGNAL(clicked()), s2); + machine.addState(s1); + machine.addState(s2); + + QObject::connect(&machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit())); + machine.setInitialState(s1); + machine.start(); + \endcode + + \sa QStateMachine::finished(), QState::finished() +*/ + +class QFinalStatePrivate : public QAbstractStatePrivate +{ + Q_DECLARE_PUBLIC(QFinalState) + +public: + QFinalStatePrivate(); +}; + +QFinalStatePrivate::QFinalStatePrivate() +{ +} + +/*! + Constructs a new QFinalState object with the given \a parent state. +*/ +QFinalState::QFinalState(QState *parent) + : QAbstractState(*new QFinalStatePrivate, parent) +{ +} + +/*! + Destroys this final state. +*/ +QFinalState::~QFinalState() +{ +} + +/*! + \reimp +*/ +void QFinalState::onEntry(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \reimp +*/ +void QFinalState::onExit(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \reimp +*/ +bool QFinalState::event(QEvent *e) +{ + return QAbstractState::event(e); +} + +QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qfinalstate.h b/src/corelib/statemachine/qfinalstate.h new file mode 100644 index 0000000..fa68394 --- /dev/null +++ b/src/corelib/statemachine/qfinalstate.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFINALSTATE_H +#define QFINALSTATE_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QFinalStatePrivate; +class Q_CORE_EXPORT QFinalState : public QAbstractState +{ + Q_OBJECT +public: + QFinalState(QState *parent = 0); + ~QFinalState(); + +protected: + void onEntry(QEvent *event); + void onExit(QEvent *event); + + bool event(QEvent *e); + +private: + Q_DISABLE_COPY(QFinalState) + Q_DECLARE_PRIVATE(QFinalState) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp new file mode 100644 index 0000000..517faa8 --- /dev/null +++ b/src/corelib/statemachine/qhistorystate.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qhistorystate.h" +#include "qhistorystate_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QHistoryState + + \brief The QHistoryState class provides a means of returning to a previously active substate. + + \since 4.6 + \ingroup statemachine + + A history state is a pseudo-state that represents the child state that the + parent state was in the last time the parent state was exited. A transition + with a history state as its target is in fact a transition to one of the + other child states of the parent state. QHistoryState is part of \l{The + State Machine Framework}. + + Use the setDefaultState() function to set the state that should be entered + if the parent state has never been entered. Example: + + \code + QStateMachine machine; + + QState *s1 = new QState(); + QState *s11 = new QState(s1); + QState *s12 = new QState(s1); + + QHistoryState *s1h = new QHistoryState(s1); + s1h->setDefaultState(s11); + + machine.addState(s1); + + QState *s2 = new QState(); + machine.addState(s2); + + QPushButton *button = new QPushButton(); + // Clicking the button will cause the state machine to enter the child state + // that s1 was in the last time s1 was exited, or the history state's default + // state if s1 has never been entered. + s1->addTransition(button, SIGNAL(clicked()), s1h); + \endcode + + By default a history state is shallow, meaning that it won't remember nested + states. This can be configured through the historyType property. +*/ + +/*! + \property QHistoryState::defaultState + + \brief the default state of this history state +*/ + +/*! + \property QHistoryState::historyType + + \brief the type of history that this history state records + + The default value of this property is QHistoryState::ShallowHistory. +*/ + +/*! + \enum QHistoryState::HistoryType + + This enum specifies the type of history that a QHistoryState records. + + \value ShallowHistory Only the immediate child states of the parent state + are recorded. In this case a transition with the history state as its + target will end up in the immediate child state that the parent was in the + last time it was exited. This is the default. + + \value DeepHistory Nested states are recorded. In this case a transition + with the history state as its target will end up in the most deeply nested + descendant state the parent was in the last time it was exited. +*/ + +QHistoryStatePrivate::QHistoryStatePrivate() + : defaultState(0) +{ +} + +QHistoryStatePrivate *QHistoryStatePrivate::get(QHistoryState *q) +{ + return q->d_func(); +} + +/*! + Constructs a new shallow history state with the given \a parent state. +*/ +QHistoryState::QHistoryState(QState *parent) + : QAbstractState(*new QHistoryStatePrivate, parent) +{ + Q_D(QHistoryState); + d->historyType = ShallowHistory; +} +/*! + Constructs a new history state of the given \a type, with the given \a + parent state. +*/ +QHistoryState::QHistoryState(HistoryType type, QState *parent) + : QAbstractState(*new QHistoryStatePrivate, parent) +{ + Q_D(QHistoryState); + d->historyType = type; +} + +/*! + Destroys this history state. +*/ +QHistoryState::~QHistoryState() +{ +} + +/*! + Returns this history state's default state. The default state indicates the + state to transition to if the parent state has never been entered before. +*/ +QAbstractState *QHistoryState::defaultState() const +{ + Q_D(const QHistoryState); + return d->defaultState; +} + +/*! + Sets this history state's default state to be the given \a state. + \a state must be a sibling of this history state. +*/ +void QHistoryState::setDefaultState(QAbstractState *state) +{ + Q_D(QHistoryState); + if (state && state->parentState() != parentState()) { + qWarning("QHistoryState::setDefaultState: state %p does not belong " + "to this history state's group (%p)", state, parentState()); + return; + } + d->defaultState = state; +} + +/*! + Returns the type of history that this history state records. +*/ +QHistoryState::HistoryType QHistoryState::historyType() const +{ + Q_D(const QHistoryState); + return d->historyType; +} + +/*! + Sets the \a type of history that this history state records. +*/ +void QHistoryState::setHistoryType(HistoryType type) +{ + Q_D(QHistoryState); + d->historyType = type; +} + +/*! + \reimp +*/ +void QHistoryState::onEntry(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \reimp +*/ +void QHistoryState::onExit(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \reimp +*/ +bool QHistoryState::event(QEvent *e) +{ + return QAbstractState::event(e); +} + +QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qhistorystate.h b/src/corelib/statemachine/qhistorystate.h new file mode 100644 index 0000000..a0682bd --- /dev/null +++ b/src/corelib/statemachine/qhistorystate.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QHISTORYSTATE_H +#define QHISTORYSTATE_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QHistoryStatePrivate; +class Q_CORE_EXPORT QHistoryState : public QAbstractState +{ + Q_OBJECT + Q_PROPERTY(QAbstractState* defaultState READ defaultState WRITE setDefaultState) + Q_PROPERTY(HistoryType historyType READ historyType WRITE setHistoryType) + Q_ENUMS(HistoryType) +public: + enum HistoryType { + ShallowHistory, + DeepHistory + }; + + QHistoryState(QState *parent = 0); + QHistoryState(HistoryType type, QState *parent = 0); + ~QHistoryState(); + + QAbstractState *defaultState() const; + void setDefaultState(QAbstractState *state); + + HistoryType historyType() const; + void setHistoryType(HistoryType type); + +protected: + void onEntry(QEvent *event); + void onExit(QEvent *event); + + bool event(QEvent *e); + +private: + Q_DISABLE_COPY(QHistoryState) + Q_DECLARE_PRIVATE(QHistoryState) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/qhistorystate_p.h b/src/corelib/statemachine/qhistorystate_p.h new file mode 100644 index 0000000..5aaa64c --- /dev/null +++ b/src/corelib/statemachine/qhistorystate_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QHISTORYSTATE_P_H +#define QHISTORYSTATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qabstractstate_p.h" + +#include + +QT_BEGIN_NAMESPACE + +class QHistoryState; +class QHistoryStatePrivate : public QAbstractStatePrivate +{ + Q_DECLARE_PUBLIC(QHistoryState) + +public: + QHistoryStatePrivate(); + + static QHistoryStatePrivate *get(QHistoryState *q); + + QAbstractState *defaultState; + QHistoryState::HistoryType historyType; + QList configuration; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/statemachine/qsignalevent.h b/src/corelib/statemachine/qsignalevent.h new file mode 100644 index 0000000..8221f68 --- /dev/null +++ b/src/corelib/statemachine/qsignalevent.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSIGNALEVENT_H +#define QSIGNALEVENT_H + +#include + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class Q_CORE_EXPORT QSignalEvent : public QEvent +{ +public: + QSignalEvent(const QObject *sender, int signalIndex, + const QList &arguments); + ~QSignalEvent(); + + inline const QObject *sender() const { return m_sender; } + inline int signalIndex() const { return m_signalIndex; } + inline QList arguments() const { return m_arguments; } + +private: + const QObject *m_sender; + int m_signalIndex; + QList m_arguments; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/qsignaleventgenerator_p.h b/src/corelib/statemachine/qsignaleventgenerator_p.h new file mode 100644 index 0000000..cf0ea1e --- /dev/null +++ b/src/corelib/statemachine/qsignaleventgenerator_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSIGNALEVENTGENERATOR_P_H +#define QSIGNALEVENTGENERATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QStateMachine; + +class QSignalEventGenerator : public QObject +{ +public: + QSignalEventGenerator(QStateMachine *parent); + + static const QMetaObject staticMetaObject; + virtual const QMetaObject *metaObject() const; + virtual void *qt_metacast(const char *); + virtual int qt_metacall(QMetaObject::Call, int, void **argv); + +private: + Q_DISABLE_COPY(QSignalEventGenerator) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp new file mode 100644 index 0000000..4caa917 --- /dev/null +++ b/src/corelib/statemachine/qsignaltransition.cpp @@ -0,0 +1,257 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsignaltransition.h" +#include "qsignaltransition_p.h" +#include "qsignalevent.h" +#include "qstate.h" +#include "qstate_p.h" +#include "qstatemachine.h" +#include "qstatemachine_p.h" +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QSignalTransition + + \brief The QSignalTransition class provides a transition based on a Qt signal. + + \since 4.6 + \ingroup statemachine + + Typically you would use the overload of QState::addTransition() that takes a + sender and signal as arguments, rather than creating QSignalTransition + objects directly. QSignalTransition is part of \l{The State Machine + Framework}. + + You can subclass QSignalTransition and reimplement eventTest() to make a + signal transition conditional; the event object passed to eventTest() will + be a QSignalEvent object. Example: + + \code + class CheckedTransition : public QSignalTransition + { + public: + CheckedTransition(QCheckBox *check) + : QSignalTransition(check, SIGNAL(stateChanged(int))) {} + protected: + bool eventTest(QEvent *e) const { + if (!QSignalTransition::eventTest(e)) + return false; + QSignalEvent *se = static_cast(e); + return (se->arguments().at(0).toInt() == Qt::Checked); + } + }; + + ... + + QCheckBox *check = new QCheckBox(); + check->setTristate(true); + + QState *s1 = new QState(); + QState *s2 = new QState(); + CheckedTransition *t1 = new CheckedTransition(check); + t1->setTargetState(s2); + s1->addTransition(t1); + \endcode +*/ + +/*! + \property QSignalTransition::senderObject + + \brief the sender object that this signal transition is associated with +*/ + +/*! + \property QSignalTransition::signal + + \brief the signal that this signal transition is associated with +*/ + +QSignalTransitionPrivate::QSignalTransitionPrivate() +{ + sender = 0; + signalIndex = -1; +} + +QSignalTransitionPrivate *QSignalTransitionPrivate::get(QSignalTransition *q) +{ + return q->d_func(); +} + +void QSignalTransitionPrivate::invalidate() +{ + Q_Q(QSignalTransition); + if (signalIndex != -1) { + QState *source = sourceState(); + QStatePrivate *source_d = QStatePrivate::get(source); + QStateMachinePrivate *mach = QStateMachinePrivate::get(source_d->machine()); + if (mach) { + mach->unregisterSignalTransition(q); + if (mach->configuration.contains(source)) + mach->registerSignalTransition(q); + } + } +} + +/*! + Constructs a new signal transition with the given \a sourceState. +*/ +QSignalTransition::QSignalTransition(QState *sourceState) + : QAbstractTransition(*new QSignalTransitionPrivate, sourceState) +{ +} + +/*! + Constructs a new signal transition associated with the given \a signal of + the given \a sender, and with the given \a sourceState. +*/ +QSignalTransition::QSignalTransition(QObject *sender, const char *signal, + QState *sourceState) + : QAbstractTransition(*new QSignalTransitionPrivate, sourceState) +{ + Q_D(QSignalTransition); + d->sender = sender; + d->signal = signal; +} + +/*! + Constructs a new signal transition associated with the given \a signal of + the given \a sender. The transition has the given \a targets and \a + sourceState. +*/ +QSignalTransition::QSignalTransition(QObject *sender, const char *signal, + const QList &targets, + QState *sourceState) + : QAbstractTransition(*new QSignalTransitionPrivate, targets, sourceState) +{ + Q_D(QSignalTransition); + d->sender = sender; + d->signal = signal; +} + +/*! + Destroys this signal transition. +*/ +QSignalTransition::~QSignalTransition() +{ +} + +/*! + Returns the sender object associated with this signal transition. +*/ +QObject *QSignalTransition::senderObject() const +{ + Q_D(const QSignalTransition); + return d->sender; +} + +/*! + Sets the \a sender object associated with this signal transition. +*/ +void QSignalTransition::setSenderObject(QObject *sender) +{ + Q_D(QSignalTransition); + if (sender == d->sender) + return; + d->sender = sender; + d->invalidate(); +} + +/*! + Returns the signal associated with this signal transition. +*/ +QByteArray QSignalTransition::signal() const +{ + Q_D(const QSignalTransition); + return d->signal; +} + +/*! + Sets the \a signal associated with this signal transition. +*/ +void QSignalTransition::setSignal(const QByteArray &signal) +{ + Q_D(QSignalTransition); + if (signal == d->signal) + return; + d->signal = signal; + d->invalidate(); +} + +/*! + \reimp + + The \a event is a QSignalEvent object. The default implementation returns + true if the event's sender and signal index match this transition, and + returns false otherwise. +*/ +bool QSignalTransition::eventTest(QEvent *event) +{ + Q_D(const QSignalTransition); + if (event->type() == QEvent::Signal) { + if (d->signalIndex == -1) + return false; + QSignalEvent *se = static_cast(event); + return (se->sender() == d->sender) + && (se->signalIndex() == d->signalIndex); + } + return false; +} + +/*! + \reimp +*/ +void QSignalTransition::onTransition(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \reimp +*/ +bool QSignalTransition::event(QEvent *e) +{ + return QAbstractTransition::event(e); +} + +QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qsignaltransition.h b/src/corelib/statemachine/qsignaltransition.h new file mode 100644 index 0000000..b485785 --- /dev/null +++ b/src/corelib/statemachine/qsignaltransition.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSIGNALTRANSITION_H +#define QSIGNALTRANSITION_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QSignalTransitionPrivate; +class Q_CORE_EXPORT QSignalTransition : public QAbstractTransition +{ + Q_OBJECT + Q_PROPERTY(QObject* senderObject READ senderObject WRITE setSenderObject) + Q_PROPERTY(QByteArray signal READ signal WRITE setSignal) +public: + QSignalTransition(QState *sourceState = 0); + QSignalTransition(QObject *sender, const char *signal, + QState *sourceState = 0); + QSignalTransition(QObject *sender, const char *signal, + const QList &targets, + QState *sourceState = 0); + ~QSignalTransition(); + + QObject *senderObject() const; + void setSenderObject(QObject *sender); + + QByteArray signal() const; + void setSignal(const QByteArray &signal); + +protected: + bool eventTest(QEvent *event); + void onTransition(QEvent *event); + + bool event(QEvent *e); + +private: + Q_DISABLE_COPY(QSignalTransition) + Q_DECLARE_PRIVATE(QSignalTransition) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/qsignaltransition_p.h b/src/corelib/statemachine/qsignaltransition_p.h new file mode 100644 index 0000000..a23e58c --- /dev/null +++ b/src/corelib/statemachine/qsignaltransition_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSIGNALTRANSITION_P_H +#define QSIGNALTRANSITION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qabstracttransition_p.h" + +QT_BEGIN_NAMESPACE + +class QSignalTransition; +class QSignalTransitionPrivate : public QAbstractTransitionPrivate +{ + Q_DECLARE_PUBLIC(QSignalTransition) +public: + QSignalTransitionPrivate(); + + static QSignalTransitionPrivate *get(QSignalTransition *q); + + void invalidate(); + + QObject *sender; + QByteArray signal; + int signalIndex; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp new file mode 100644 index 0000000..e42e463 --- /dev/null +++ b/src/corelib/statemachine/qstate.cpp @@ -0,0 +1,497 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstate.h" +#include "qstate_p.h" +#include "qhistorystate.h" +#include "qhistorystate_p.h" +#include "qabstracttransition.h" +#include "qabstracttransition_p.h" +#include "qsignaltransition.h" +#include "qstatemachine.h" +#include "qstatemachine_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QState + + \brief The QState class provides a general-purpose state for QStateMachine. + + \since 4.6 + \ingroup statemachine + + QState objects can have child states, and can have transitions to other + states. QState is part of \l{The State Machine Framework}. + + The addTransition() function adds a transition. The removeTransition() + function removes a transition. + + The assignProperty() function is used for defining property assignments that + should be performed when a state is entered. + + Top-level states must be passed QStateMachine::rootState() as their parent + state, or added to a state machine using QStateMachine::addState(). + + \section1 States with Child States + + The childMode property determines how child states are treated. For + non-parallel state groups, the setInitialState() function must be called to + set the initial state. The child states are mutually exclusive states, and + the state machine needs to know which child state to enter when the parent + state is the target of a transition. + + The state emits the QState::finished() signal when a final child state + (QFinalState) is entered. + + The setErrorState() sets the state's error state. The error state is the + state that the state machine will transition to if an error is detected when + attempting to enter the state (e.g. because no initial state has been set). + +*/ + +/*! + \property QState::initialState + + \brief the initial state of this state (one of its child states) +*/ + +/*! + \property QState::errorState + + \brief the error state of this state +*/ + +/*! + \property QState::childMode + + \brief the child mode of this state + + The default value of this property is QState::ExclusiveStates. +*/ + +/*! + \enum QState::ChildMode + + This enum specifies how a state's child states are treated. + + \value ExclusiveStates The child states are mutually exclusive and an + initial state must be set by calling QState::setInitialState(). + + \value ParallelStates The child states are parallel. When the parent state + is entered, all its child states are entered in parallel. +*/ + +QStatePrivate::QStatePrivate() + : errorState(0), initialState(0), childMode(QState::ExclusiveStates) +{ +} + +QStatePrivate::~QStatePrivate() +{ +} + +QStatePrivate *QStatePrivate::get(QState *q) +{ + if (!q) + return 0; + return q->d_func(); +} + +const QStatePrivate *QStatePrivate::get(const QState *q) +{ + if (!q) + return 0; + return q->d_func(); +} + +void QStatePrivate::emitFinished() +{ + Q_Q(QState); + emit q->finished(); +} + +void QStatePrivate::emitPolished() +{ + Q_Q(QState); + emit q->polished(); +} + +/*! + Constructs a new state with the given \a parent state. +*/ +QState::QState(QState *parent) + : QAbstractState(*new QStatePrivate, parent) +{ +} + +/*! + Constructs a new state with the given \a childMode and the given \a parent + state. +*/ +QState::QState(ChildMode childMode, QState *parent) + : QAbstractState(*new QStatePrivate, parent) +{ + Q_D(QState); + d->childMode = childMode; +} + +/*! + \internal +*/ +QState::QState(QStatePrivate &dd, QState *parent) + : QAbstractState(dd, parent) +{ +} + +/*! + Destroys this state. +*/ +QState::~QState() +{ +} + +QList QStatePrivate::childStates() const +{ + QList result; + QList::const_iterator it; + for (it = children.constBegin(); it != children.constEnd(); ++it) { + QAbstractState *s = qobject_cast(*it); + if (!s || qobject_cast(s)) + continue; + result.append(s); + } + return result; +} + +QList QStatePrivate::historyStates() const +{ + QList result; + QList::const_iterator it; + for (it = children.constBegin(); it != children.constEnd(); ++it) { + QHistoryState *h = qobject_cast(*it); + if (h) + result.append(h); + } + return result; +} + +QList QStatePrivate::transitions() const +{ + QList result; + QList::const_iterator it; + for (it = children.constBegin(); it != children.constEnd(); ++it) { + QAbstractTransition *t = qobject_cast(*it); + if (t) + result.append(t); + } + return result; +} + +/*! + Instructs this state to set the property with the given \a name of the given + \a object to the given \a value when the state is entered. + + \sa polished() +*/ +void QState::assignProperty(QObject *object, const char *name, + const QVariant &value) +{ + Q_D(QState); + if (!object) { + qWarning("QState::assignProperty: cannot assign property '%s' of null object", name); + return; + } + for (int i = 0; i < d->propertyAssignments.size(); ++i) { + QPropertyAssignment &assn = d->propertyAssignments[i]; + if ((assn.object == object) && (assn.propertyName == name)) { + assn.value = value; + return; + } + } + d->propertyAssignments.append(QPropertyAssignment(object, name, value)); +} + +/*! + Returns this state group's error state. + + \sa QStateMachine::errorState(), QStateMachine::setErrorState() +*/ +QAbstractState *QState::errorState() const +{ + Q_D(const QState); + return d->errorState; +} + +/*! + Sets this state's error state to be the given \a state. If the error state + is not set, or if it is set to 0, the state will inherit its parent's error + state recursively. + + \sa QStateMachine::setErrorState(), QStateMachine::errorState() +*/ +void QState::setErrorState(QAbstractState *state) +{ + Q_D(QState); + if (state != 0 && state->machine() != machine()) { + qWarning("QState::setErrorState: error state cannot belong " + "to a different state machine"); + return; + } + if (state != 0 && state->machine() != 0 && state->machine()->rootState() == state) { + qWarning("QStateMachine::setErrorState: root state cannot be error state"); + return; + } + + d->errorState = state; +} + +/*! + Adds the given \a transition. The transition has this state as the source. + This state takes ownership of the transition. If the transition is successfully + added, the function will return the \a transition pointer. Otherwise it will return null. +*/ +QAbstractTransition *QState::addTransition(QAbstractTransition *transition) +{ + Q_D(QState); + if (!transition) { + qWarning("QState::addTransition: cannot add null transition"); + return 0; + } + + // machine() will always be non-null for root state + if (machine() != 0 && machine()->rootState() == this) { + qWarning("QState::addTransition: cannot add transition from root state"); + return 0; + } + + const QList > &targets = QAbstractTransitionPrivate::get(transition)->targetStates; + for (int i = 0; i < targets.size(); ++i) { + QAbstractState *t = targets.at(i); + if (!t) { + qWarning("QState::addTransition: cannot add transition to null state"); + return 0; + } + if ((QAbstractStatePrivate::get(t)->machine() != d->machine()) + && QAbstractStatePrivate::get(t)->machine() && d->machine()) { + qWarning("QState::addTransition: cannot add transition " + "to a state in a different state machine"); + return 0; + } + } + transition->setParent(this); + if (machine() != 0 && machine()->configuration().contains(this)) + QStateMachinePrivate::get(machine())->registerTransitions(this); + return transition; +} + +/*! + Adds a transition associated with the given \a signal of the given \a sender + object, and returns the new QSignalTransition object. The transition has + this state as the source, and the given \a target as the target state. +*/ +QSignalTransition *QState::addTransition(QObject *sender, const char *signal, + QAbstractState *target) +{ + if (!sender) { + qWarning("QState::addTransition: sender cannot be null"); + return 0; + } + if (!signal) { + qWarning("QState::addTransition: signal cannot be null"); + return 0; + } + if (!target) { + qWarning("QState::addTransition: cannot add transition to null state"); + return 0; + } + if (*signal && sender->metaObject()->indexOfSignal(signal+1) == -1) { + qWarning("QState::addTransition: no such signal %s::%s", + sender->metaObject()->className(), signal+1); + return 0; + } + QSignalTransition *trans = new QSignalTransition(sender, signal, QList() << target); + addTransition(trans); + return trans; +} + +namespace { + +// ### Make public? +class UnconditionalTransition : public QAbstractTransition +{ +public: + UnconditionalTransition(QAbstractState *target) + : QAbstractTransition(QList() << target) {} +protected: + void onTransition(QEvent *) {} + bool eventTest(QEvent *) { return true; } +}; + +} // namespace + +/*! + Adds an unconditional transition from this state to the given \a target + state, and returns then new transition object. +*/ +QAbstractTransition *QState::addTransition(QAbstractState *target) +{ + if (!target) { + qWarning("QState::addTransition: cannot add transition to null state"); + return 0; + } + UnconditionalTransition *trans = new UnconditionalTransition(target); + return addTransition(trans); +} + +/*! + Removes the given \a transition from this state. The state releases + ownership of the transition. + + \sa addTransition() +*/ +void QState::removeTransition(QAbstractTransition *transition) +{ + Q_D(QState); + if (!transition) { + qWarning("QState::removeTransition: cannot remove null transition"); + return; + } + if (transition->sourceState() != this) { + qWarning("QState::removeTransition: transition %p's source state (%p)" + " is different from this state (%p)", + transition, transition->sourceState(), this); + return; + } + QStateMachinePrivate *mach = QStateMachinePrivate::get(d->machine()); + if (mach) + mach->unregisterTransition(transition); + transition->setParent(0); +} + +/*! + \reimp +*/ +void QState::onEntry(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \reimp +*/ +void QState::onExit(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + Returns this state's initial state, or 0 if the state has no initial state. +*/ +QAbstractState *QState::initialState() const +{ + Q_D(const QState); + return d->initialState; +} + +/*! + Sets this state's initial state to be the given \a state. + \a state has to be a child of this state. +*/ +void QState::setInitialState(QAbstractState *state) +{ + Q_D(QState); + if (d->childMode == QState::ParallelStates) { + qWarning("QState::setInitialState: ignoring attempt to set initial state " + "of parallel state group %p", this); + return; + } + if (state && (state->parentState() != this)) { + qWarning("QState::setInitialState: state %p is not a child of this state (%p)", + state, this); + return; + } + d->initialState = state; +} + +/*! + Returns the child mode of this state. +*/ +QState::ChildMode QState::childMode() const +{ + Q_D(const QState); + return d->childMode; +} + +/*! + Sets the child \a mode of this state. +*/ +void QState::setChildMode(ChildMode mode) +{ + Q_D(QState); + d->childMode = mode; +} + +/*! + \reimp +*/ +bool QState::event(QEvent *e) +{ + return QAbstractState::event(e); +} + +/*! + \fn QState::finished() + + This signal is emitted when a final child state of this state is entered. + + \sa QFinalState +*/ + +/*! + \fn QState::polished() + + This signal is emitted when all properties have been assigned their final value. + + \sa QState::assignProperty(), QAbstractTransition::addAnimation() +*/ + +QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qstate.h b/src/corelib/statemachine/qstate.h new file mode 100644 index 0000000..6729c69 --- /dev/null +++ b/src/corelib/statemachine/qstate.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTATE_H +#define QSTATE_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QAbstractTransition; +class QSignalTransition; + +class QStatePrivate; +class Q_CORE_EXPORT QState : public QAbstractState +{ + Q_OBJECT + Q_PROPERTY(QAbstractState* initialState READ initialState WRITE setInitialState) + Q_PROPERTY(QAbstractState* errorState READ errorState WRITE setErrorState) + Q_PROPERTY(ChildMode childMode READ childMode WRITE setChildMode) + Q_ENUMS(ChildMode) +public: + enum ChildMode { + ExclusiveStates, + ParallelStates + }; + + QState(QState *parent = 0); + QState(ChildMode childMode, QState *parent = 0); + ~QState(); + + QAbstractState *errorState() const; + void setErrorState(QAbstractState *state); + + QAbstractTransition *addTransition(QAbstractTransition *transition); + QSignalTransition *addTransition(QObject *sender, const char *signal, QAbstractState *target); + QAbstractTransition *addTransition(QAbstractState *target); + void removeTransition(QAbstractTransition *transition); + + QAbstractState *initialState() const; + void setInitialState(QAbstractState *state); + + ChildMode childMode() const; + void setChildMode(ChildMode mode); + + void assignProperty(QObject *object, const char *name, + const QVariant &value); + +Q_SIGNALS: + void finished(); + void polished(); + +protected: + void onEntry(QEvent *event); + void onExit(QEvent *event); + + bool event(QEvent *e); + +protected: + QState(QStatePrivate &dd, QState *parent); + +private: + Q_DISABLE_COPY(QState) + Q_DECLARE_PRIVATE(QState) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h new file mode 100644 index 0000000..1f913b4 --- /dev/null +++ b/src/corelib/statemachine/qstate_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTATE_P_H +#define QSTATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qabstractstate_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +struct QPropertyAssignment +{ + QPropertyAssignment() + : object(0) {} + QPropertyAssignment(QObject *o, const QByteArray &n, + const QVariant &v, bool es = true) + : object(o), propertyName(n), value(v), explicitlySet(es) + {} + QObject *object; + QByteArray propertyName; + QVariant value; + bool explicitlySet; +}; + +class QAbstractTransition; +class QHistoryState; + +class QState; +class Q_CORE_EXPORT QStatePrivate : public QAbstractStatePrivate +{ + Q_DECLARE_PUBLIC(QState) +public: + QStatePrivate(); + ~QStatePrivate(); + + static QStatePrivate *get(QState *q); + static const QStatePrivate *get(const QState *q); + + QList childStates() const; + QList historyStates() const; + QList transitions() const; + + void emitFinished(); + void emitPolished(); + + QAbstractState *errorState; + QAbstractState *initialState; + QState::ChildMode childMode; + + QList propertyAssignments; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp new file mode 100644 index 0000000..744515b --- /dev/null +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -0,0 +1,2216 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstatemachine.h" +#include "qstate.h" +#include "qstate_p.h" +#include "qstatemachine_p.h" +#include "qabstracttransition.h" +#include "qabstracttransition_p.h" +#include "qsignaltransition.h" +#include "qsignaltransition_p.h" +#include "qsignalevent.h" +#include "qsignaleventgenerator_p.h" +#include "qabstractstate.h" +#include "qabstractstate_p.h" +#include "qfinalstate.h" +#include "qhistorystate.h" +#include "qhistorystate_p.h" +#include "private/qobject_p.h" +#include "private/qthread_p.h" + +#ifndef QT_NO_STATEMACHINE_EVENTFILTER +#include "qeventtransition.h" +#include "qeventtransition_p.h" +#include "qwrappedevent.h" +#endif + +#ifndef QT_NO_ANIMATION +#include "qpropertyanimation.h" +#include "qanimationgroup.h" +#include +#endif + +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QStateMachine + \reentrant + + \brief The QStateMachine class provides a hierarchical finite state machine. + + \since 4.6 + \ingroup statemachine + + QStateMachine is based on the concepts and notation of + \l{Statecharts: A visual formalism for complex + systems}{Statecharts}. QStateMachine is part of \l{The State + Machine Framework}. + + A state machine manages a set of states (classes that inherit from + QAbstractState) and transitions (descendants of + QAbstractTransition) between those states; these states and + transitions define a state graph. Once a state graph has been + built, the state machine can execute it. \l{QStateMachine}'s + execution algorithm is based on the \l{State Chart XML: State + Machine Notation for Control Abstraction}{State Chart XML (SCXML)} + algorithm. The framework's \l{The State Machine + Framework}{overview} gives several state graphs and the code to + build them. + + The rootState() is the parent of all top-level states in the + machine; it is used, for instance, when the state graph is + deleted. It is created by the machine. + + Use the addState() function to add a state to the state machine. + All top-level states are added to the root state. States are + removed with the removeState() function. Removing states while the + machine is running is discouraged. + + Before the machine can be started, the \l{initialState}{initial + state} must be set. The initial state is the state that the + machine enters when started. You can then start() the state + machine. The started() signal is emitted when the initial state is + entered. + + The machine is event driven and keeps its own event loop. Events + are posted to the machine through postEvent(). Note that this + means that it executes asynchronously, and that it will not + progress without a running event loop. You will normally not have + to post events to the machine directly as Qt's transitions, e.g., + QEventTransition and its subclasses, handle this. But for custom + transitions triggered by events, postEvent() is useful. + + The state machine processes events and takes transitions until a + top-level final state is entered; the state machine then emits the + finished() signal. You can also stop() the state machine + explicitly. The stopped() signal is emitted in this case. + + The following snippet shows a state machine that will finish when a button + is clicked: + + \code + QPushButton button; + + QStateMachine machine; + QState *s1 = new QState(); + s1->assignProperty(&button, "text", "Click me"); + + QFinalState *s2 = new QFinalState(); + s1->addTransition(&button, SIGNAL(clicked()), s2); + + machine.addState(s1); + machine.addState(s2); + machine.setInitialState(s1); + machine.start(); + \endcode + + This code example uses QState, which inherits QAbstractState. The + QState class provides a state that you can use to set properties + and invoke methods on \l{QObject}s when the state is entered or + exited. It also contains convenience functions for adding + transitions, e.g., \l{QSignalTransition}s as in this example. See + the QState class description for further details. + + If an error is encountered, the machine will enter the + \l{errorState}{error state}, which is a special state created by + the machine. The types of errors possible are described by the + \l{QStateMachine::}{Error} enum. After the error state is entered, + the type of the error can be retrieved with error(). The execution + of the state graph will not stop when the error state is entered. + So it is possible to handle the error, for instance, by connecting + to the \l{QAbstractState::}{entered()} signal of the error state. + It is also possible to set a custom error state with + setErrorState(). + + \omit This stuff will be moved elsewhere +This is + typically used in conjunction with \l{Signals and Slots}{signals}; the + signals determine the flow of the state graph, whereas the states' property + assignments and method invocations are the actions. + + The postEvent() function posts an event to the state machine. This is useful + when you are using custom events to trigger transitions. + \endomit + + \sa QAbstractState, QAbstractTransition, QState, {The State Machine Framework} +*/ + +/*! + \property QStateMachine::rootState + + \brief the root state of this state machine +*/ + +/*! + \property QStateMachine::initialState + + \brief the initial state of this state machine + + The initial state must be one of the rootState()'s child states. +*/ + +/*! + \property QStateMachine::errorState + + \brief the error state of this state machine +*/ + +/*! + \property QStateMachine::errorString + + \brief the error string of this state machine +*/ + +/*! + \property QStateMachine::globalRestorePolicy + + \brief the restore policy for states of this state machine. + + The default value of this property is + QStateMachine::DoNotRestoreProperties. +*/ + +#ifndef QT_NO_ANIMATION +/*! + \property QStateMachine::animationsEnabled + + \brief whether animations are enabled + + The default value of this property is true. + + \sa QAbstractTransition::addAnimation() +*/ +#endif + +// #define QSTATEMACHINE_DEBUG + +QStateMachinePrivate::QStateMachinePrivate() +{ + state = NotRunning; + processing = false; + processingScheduled = false; + stop = false; + error = QStateMachine::NoError; + globalRestorePolicy = QStateMachine::DoNotRestoreProperties; + rootState = 0; + initialErrorStateForRoot = 0; + signalEventGenerator = 0; +#ifndef QT_NO_ANIMATION + animationsEnabled = true; +#endif +} + +QStateMachinePrivate::~QStateMachinePrivate() +{ + qDeleteAll(internalEventQueue); + qDeleteAll(externalEventQueue); +} + +QStateMachinePrivate *QStateMachinePrivate::get(QStateMachine *q) +{ + if (q) + return q->d_func(); + return 0; +} + +static QEvent *cloneEvent(QEvent *e) +{ + switch (e->type()) { + case QEvent::None: + return new QEvent(*e); + case QEvent::Timer: + return new QTimerEvent(*static_cast(e)); + default: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + } + return 0; +} + +const QStateMachinePrivate::Handler qt_kernel_statemachine_handler = { + cloneEvent +}; + +const QStateMachinePrivate::Handler *QStateMachinePrivate::handler = &qt_kernel_statemachine_handler; + +Q_CORE_EXPORT const QStateMachinePrivate::Handler *qcoreStateMachineHandler() +{ + return &qt_kernel_statemachine_handler; +} + +static int indexOfDescendant(QState *s, QAbstractState *desc) +{ + QList childStates = QStatePrivate::get(s)->childStates(); + for (int i = 0; i < childStates.size(); ++i) { + QAbstractState *c = childStates.at(i); + if ((c == desc) || QStateMachinePrivate::isDescendantOf(desc, c)) { + return i; + } + } + return -1; +} + +bool QStateMachinePrivate::stateEntryLessThan(QAbstractState *s1, QAbstractState *s2) +{ + if (s1->parent() == s2->parent()) { + return s1->children().indexOf(s1) + < s2->children().indexOf(s2); + } else if (isDescendantOf(s1, s2)) { + return false; + } else if (isDescendantOf(s2, s1)) { + return true; + } else { + QState *lca = findLCA(QList() << s1 << s2); + Q_ASSERT(lca != 0); + return (indexOfDescendant(lca, s1) < indexOfDescendant(lca, s2)); + } +} + +bool QStateMachinePrivate::stateExitLessThan(QAbstractState *s1, QAbstractState *s2) +{ + if (s1->parent() == s2->parent()) { + return s1->children().indexOf(s1) + < s2->children().indexOf(s2); + } else if (isDescendantOf(s1, s2)) { + return true; + } else if (isDescendantOf(s2, s1)) { + return false; + } else { + QState *lca = findLCA(QList() << s1 << s2); + Q_ASSERT(lca != 0); + return (indexOfDescendant(lca, s1) < indexOfDescendant(lca, s2)); + } +} + +QState *QStateMachinePrivate::findLCA(const QList &states) +{ + if (states.isEmpty()) + return 0; + QList ancestors = properAncestors(states.at(0), 0); + for (int i = 0; i < ancestors.size(); ++i) { + QState *anc = ancestors.at(i); + bool ok = true; + for (int j = states.size() - 1; (j > 0) && ok; --j) { + const QAbstractState *s = states.at(j); + if (!isDescendantOf(s, anc)) + ok = false; + } + if (ok) + return anc; + } + return 0; +} + +bool QStateMachinePrivate::isPreempted(const QAbstractState *s, const QSet &transitions) const +{ + QSet::const_iterator it; + for (it = transitions.constBegin(); it != transitions.constEnd(); ++it) { + QAbstractTransition *t = *it; + QList lst = t->targetStates(); + if (!lst.isEmpty()) { + lst.prepend(t->sourceState()); + QAbstractState *lca = findLCA(lst); + if (isDescendantOf(s, lca)) { +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q_func() << ":" << transitions << "preempts selection of a transition from" + << s << "because" << s << "is a descendant of" << lca; +#endif + return true; + } + } + } + return false; +} + +QSet QStateMachinePrivate::selectTransitions(QEvent *event) const +{ + Q_Q(const QStateMachine); + QSet enabledTransitions; + QSet::const_iterator it; + const_cast(q)->beginSelectTransitions(event); + for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { + QAbstractState *state = *it; + if (!isAtomic(state)) + continue; + if (isPreempted(state, enabledTransitions)) + continue; + QList lst = properAncestors(state, 0); + if (QState *grp = qobject_cast(state)) + lst.prepend(grp); + bool found = false; + for (int j = 0; (j < lst.size()) && !found; ++j) { + QState *s = lst.at(j); + QList transitions = QStatePrivate::get(s)->transitions(); + for (int k = 0; k < transitions.size(); ++k) { + QAbstractTransition *t = transitions.at(k); + if (QAbstractTransitionPrivate::get(t)->callEventTest(event)) { +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": selecting transition" << t; +#endif + enabledTransitions.insert(t); + found = true; + break; + } + } + } + } + const_cast(q)->endSelectTransitions(event); + return enabledTransitions; +} + +void QStateMachinePrivate::microstep(QEvent *event, const QList &enabledTransitions) +{ +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q_func() << ": begin microstep( enabledTransitions:" << enabledTransitions << ")"; + qDebug() << q_func() << ": configuration before exiting states:" << configuration; +#endif + QList exitedStates = exitStates(event, enabledTransitions); +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q_func() << ": configuration after exiting states:" << configuration; +#endif + executeTransitionContent(event, enabledTransitions); + QList enteredStates = enterStates(event, enabledTransitions); + applyProperties(enabledTransitions, exitedStates, enteredStates); +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q_func() << ": configuration after entering states:" << configuration; + qDebug() << q_func() << ": end microstep"; +#endif +} + +QList QStateMachinePrivate::exitStates(QEvent *event, const QList &enabledTransitions) +{ +// qDebug() << "exitStates(" << enabledTransitions << ")"; + QSet statesToExit; +// QSet statesToSnapshot; + for (int i = 0; i < enabledTransitions.size(); ++i) { + QAbstractTransition *t = enabledTransitions.at(i); + QList lst = t->targetStates(); + if (lst.isEmpty()) + continue; + lst.prepend(t->sourceState()); + QAbstractState *lca = findLCA(lst); + if (lca == 0) { + setError(QStateMachine::NoCommonAncestorForTransitionError, t->sourceState()); + lst = pendingErrorStates.toList(); + lst.prepend(t->sourceState()); + + lca = findLCA(lst); + Q_ASSERT(lca != 0); + } + + { + QSet::const_iterator it; + for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { + QAbstractState *s = *it; + if (isDescendantOf(s, lca)) + statesToExit.insert(s); + } + } + } + QList statesToExit_sorted = statesToExit.toList(); + qSort(statesToExit_sorted.begin(), statesToExit_sorted.end(), stateExitLessThan); + for (int i = 0; i < statesToExit_sorted.size(); ++i) { + QAbstractState *s = statesToExit_sorted.at(i); + if (QState *grp = qobject_cast(s)) { + QList hlst = QStatePrivate::get(grp)->historyStates(); + for (int j = 0; j < hlst.size(); ++j) { + QHistoryState *h = hlst.at(j); + QHistoryStatePrivate::get(h)->configuration.clear(); + QSet::const_iterator it; + for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { + QAbstractState *s0 = *it; + if (QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) { + if (isAtomic(s0) && isDescendantOf(s0, s)) + QHistoryStatePrivate::get(h)->configuration.append(s0); + } else if (s0->parentState() == s) { + QHistoryStatePrivate::get(h)->configuration.append(s0); + } + } +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q_func() << ": recorded" << ((QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) ? "deep" : "shallow") + << "history for" << s << "in" << h << ":" << QHistoryStatePrivate::get(h)->configuration; +#endif + } + } + } + for (int i = 0; i < statesToExit_sorted.size(); ++i) { + QAbstractState *s = statesToExit_sorted.at(i); +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q_func() << ": exiting" << s; +#endif + QAbstractStatePrivate::get(s)->callOnExit(event); + configuration.remove(s); + QAbstractStatePrivate::get(s)->emitExited(); + } + return statesToExit_sorted; +} + +void QStateMachinePrivate::executeTransitionContent(QEvent *event, const QList &enabledTransitions) +{ + for (int i = 0; i < enabledTransitions.size(); ++i) { + QAbstractTransition *t = enabledTransitions.at(i); +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q_func() << ": triggering" << t; +#endif + QAbstractTransitionPrivate::get(t)->callOnTransition(event); + } +} + +QList QStateMachinePrivate::enterStates(QEvent *event, const QList &enabledTransitions) +{ +#ifdef QSTATEMACHINE_DEBUG + Q_Q(QStateMachine); +#endif +// qDebug() << "enterStates(" << enabledTransitions << ")"; + QSet statesToEnter; + QSet statesForDefaultEntry; + + if (pendingErrorStates.isEmpty()) { + for (int i = 0; i < enabledTransitions.size(); ++i) { + QAbstractTransition *t = enabledTransitions.at(i); + QList lst = t->targetStates(); + if (lst.isEmpty()) + continue; + lst.prepend(t->sourceState()); + QState *lca = findLCA(lst); + for (int j = 1; j < lst.size(); ++j) { + QAbstractState *s = lst.at(j); + addStatesToEnter(s, lca, statesToEnter, statesForDefaultEntry); + if (isParallel(lca)) { + QList lcac = QStatePrivate::get(lca)->childStates(); + foreach (QAbstractState* child,lcac) { + if (!statesToEnter.contains(child)) + addStatesToEnter(child,lca,statesToEnter,statesForDefaultEntry); + } + } + } + } + } + + // Did an error occur while selecting transitions? Then we enter the error state. + if (!pendingErrorStates.isEmpty()) { + statesToEnter.clear(); + statesToEnter = pendingErrorStates; + statesForDefaultEntry = pendingErrorStatesForDefaultEntry; + pendingErrorStates.clear(); + pendingErrorStatesForDefaultEntry.clear(); + } + + QList statesToEnter_sorted = statesToEnter.toList(); + qSort(statesToEnter_sorted.begin(), statesToEnter_sorted.end(), stateEntryLessThan); + + for (int i = 0; i < statesToEnter_sorted.size(); ++i) { + QAbstractState *s = statesToEnter_sorted.at(i); +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": entering" << s; +#endif + configuration.insert(s); + registerTransitions(s); + QAbstractStatePrivate::get(s)->callOnEntry(event); + QAbstractStatePrivate::get(s)->emitEntered(); + if (statesForDefaultEntry.contains(s)) { + // ### executeContent(s.initial.transition.children()) + } + if (isFinal(s)) { + QState *parent = s->parentState(); + if (parent) { + QState *grandparent = parent->parentState(); +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": emitting finished signal for" << parent; +#endif + QStatePrivate::get(parent)->emitFinished(); + if (grandparent && isParallel(grandparent)) { + bool allChildStatesFinal = true; + QList childStates = QStatePrivate::get(grandparent)->childStates(); + for (int j = 0; j < childStates.size(); ++j) { + QAbstractState *cs = childStates.at(j); + if (!isInFinalState(cs)) { + allChildStatesFinal = false; + break; + } + } + if (allChildStatesFinal) { +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": emitting finished signal for" << grandparent; +#endif + QStatePrivate::get(grandparent)->emitFinished(); + } + } + } + } + } + { + QSet::const_iterator it; + for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { + if (isFinal(*it) && (*it)->parentState() == rootState) { + processing = false; + stopProcessingReason = Finished; + break; + } + } + } +// qDebug() << "configuration:" << configuration.toList(); + return statesToEnter_sorted; +} + +void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, + QSet &statesToEnter, + QSet &statesForDefaultEntry) +{ + if (QHistoryState *h = qobject_cast(s)) { + QList hconf = QHistoryStatePrivate::get(h)->configuration; + if (!hconf.isEmpty()) { + for (int k = 0; k < hconf.size(); ++k) { + QAbstractState *s0 = hconf.at(k); + addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry); + } + #ifdef QSTATEMACHINE_DEBUG + qDebug() <historyType == QHistoryState::DeepHistory) ? "deep" : "shallow") + << "history from" << s << ":" << hconf; + #endif + } else { + QList hlst; + if (QHistoryStatePrivate::get(h)->defaultState) + hlst.append(QHistoryStatePrivate::get(h)->defaultState); + + if (hlst.isEmpty()) { + setError(QStateMachine::NoDefaultStateInHistoryStateError, h); + } else { + for (int k = 0; k < hlst.size(); ++k) { + QAbstractState *s0 = hlst.at(k); + addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry); + } + #ifdef QSTATEMACHINE_DEBUG + qDebug() << q_func() << ": initial history targets for" << s << ":" << hlst; + #endif + } + } + } else { + statesToEnter.insert(s); + if (isParallel(s)) { + QState *grp = qobject_cast(s); + QList lst = QStatePrivate::get(grp)->childStates(); + for (int i = 0; i < lst.size(); ++i) { + QAbstractState *child = lst.at(i); + addStatesToEnter(child, grp, statesToEnter, statesForDefaultEntry); + } + } else if (isCompound(s)) { + statesForDefaultEntry.insert(s); + QState *grp = qobject_cast(s); + QAbstractState *initial = grp->initialState(); + if (initial != 0) { + addStatesToEnter(initial, grp, statesToEnter, statesForDefaultEntry); + } else { + setError(QStateMachine::NoInitialStateError, grp); + return; + } + } + QList ancs = properAncestors(s, root); + for (int i = 0; i < ancs.size(); ++i) { + QState *anc = ancs.at(i); + if (!anc->parentState()) + continue; + statesToEnter.insert(anc); + if (isParallel(anc)) { + QList lst = QStatePrivate::get(anc)->childStates(); + for (int j = 0; j < lst.size(); ++j) { + QAbstractState *child = lst.at(j); + bool hasDescendantInList = false; + QSet::const_iterator it; + for (it = statesToEnter.constBegin(); it != statesToEnter.constEnd(); ++it) { + if (isDescendantOf(*it, child)) { + hasDescendantInList = true; + break; + } + } + if (!hasDescendantInList) + addStatesToEnter(child, anc, statesToEnter, statesForDefaultEntry); + } + } + } + } +} + +void QStateMachinePrivate::applyProperties(const QList &transitionList, + const QList &exitedStates, + const QList &enteredStates) +{ + Q_Q(QStateMachine); +#ifdef QT_NO_ANIMATION + Q_UNUSED(transitionList); +#endif + // Process the property assignments of the entered states. + QHash > propertyAssignmentsForState; + QHash pendingRestorables = registeredRestorables; + for (int i = 0; i < enteredStates.size(); ++i) { + QState *s = qobject_cast(enteredStates.at(i)); + if (!s) + continue; + + QList assignments = QStatePrivate::get(s)->propertyAssignments; + for (int j = 0; j < assignments.size(); ++j) { + const QPropertyAssignment &assn = assignments.at(j); + if (globalRestorePolicy == QStateMachine::RestoreProperties) { + registerRestorable(assn.object, assn.propertyName); + } + pendingRestorables.remove(RestorableId(assn.object, assn.propertyName)); + propertyAssignmentsForState[s].append(assn); + } + + // Remove pending restorables for all parent states to avoid restoring properties + // before the state that assigned them is exited. If state does not explicitly + // assign a property which is assigned by the parent, it inherits the parent's assignment. + QState *parentState = s; + while ((parentState = parentState->parentState()) != 0) { + assignments = QStatePrivate::get(parentState)->propertyAssignments; + for (int j=0; j 0) + propertyAssignmentsForState[s].append(assn); + } + } + } + if (!pendingRestorables.isEmpty()) { + QAbstractState *s; + if (!enteredStates.isEmpty()) + s = enteredStates.last(); // ### handle if parallel + else + s = 0; + propertyAssignmentsForState[s] << restorablesToPropertyList(pendingRestorables); + } + +#ifndef QT_NO_ANIMATION + // Gracefully terminate playing animations for states that are exited. + for (int i = 0; i < exitedStates.size(); ++i) { + QAbstractState *s = exitedStates.at(i); + QList animations = animationsForState.take(s); + for (int j = 0; j < animations.size(); ++j) { + QAbstractAnimation *anim = animations.at(j); + QObject::disconnect(anim, SIGNAL(finished()), q, SLOT(_q_animationFinished())); + stateForAnimation.remove(anim); + + // Stop the (top-level) animation. + // ### Stopping nested animation has weird behavior. + QAbstractAnimation *topLevelAnim = anim; + while (QAnimationGroup *group = topLevelAnim->group()) + topLevelAnim = group; + topLevelAnim->stop(); + + if (resetAnimationEndValues.contains(anim)) { + qobject_cast(anim)->setEndValue(QVariant()); // ### generalize + resetAnimationEndValues.remove(anim); + } + QPropertyAssignment assn = propertyForAnimation.take(anim); + Q_ASSERT(assn.object != 0); + // If there is no property assignment that sets this property, + // set the property to its target value. + bool found = false; + QHash >::const_iterator it; + for (it = propertyAssignmentsForState.constBegin(); it != propertyAssignmentsForState.constEnd(); ++it) { + const QList &assignments = it.value(); + for (int k = 0; k < assignments.size(); ++k) { + if ((assignments.at(k).object == assn.object) + && (assignments.at(k).propertyName == assn.propertyName)) { + found = true; + break; + } + } + } + if (!found) { + assn.object->setProperty(assn.propertyName, assn.value); + } + } + } + + // Find the animations to use for the state change. + QList selectedAnimations; + if (animationsEnabled) { + for (int i = 0; i < transitionList.size(); ++i) { + QAbstractTransition *transition = transitionList.at(i); + + selectedAnimations << transition->animations(); + selectedAnimations << defaultAnimationsForSource.values(transition->sourceState()); + + QList targetStates = transition->targetStates(); + for (int j=0; j >::iterator it; + for (it = propertyAssignmentsForState.begin(); it != propertyAssignmentsForState.end(); ) { + QList::iterator it2; + QAbstractState *s = it.key(); + QList &assignments = it.value(); + for (it2 = assignments.begin(); it2 != assignments.end(); ) { + QPair, QList > ret; + ret = initializeAnimation(anim, *it2); + QList handlers = ret.first; + if (!handlers.isEmpty()) { + for (int j = 0; j < handlers.size(); ++j) { + QAbstractAnimation *a = handlers.at(j); + propertyForAnimation.insert(a, *it2); + stateForAnimation.insert(a, s); + animationsForState[s].append(a); + // ### connect to just the top-level animation? + QObject::disconnect(a, SIGNAL(finished()), q, SLOT(_q_animationFinished())); + QObject::connect(a, SIGNAL(finished()), q, SLOT(_q_animationFinished())); + } + it2 = assignments.erase(it2); + } else { + ++it2; + } + for (int j = 0; j < ret.second.size(); ++j) + resetAnimationEndValues.insert(ret.second.at(j)); + } + if (assignments.isEmpty()) + it = propertyAssignmentsForState.erase(it); + else + ++it; + } + // We require that at least one animation is valid. + // ### generalize + QList variantAnims = qFindChildren(anim); + if (QVariantAnimation *va = qobject_cast(anim)) + variantAnims.append(va); + + bool hasValidEndValue = false; + for (int j = 0; j < variantAnims.size(); ++j) { + if (variantAnims.at(j)->endValue().isValid()) { + hasValidEndValue = true; + break; + } + } + + if (hasValidEndValue) { + anim->start(); + } + } +#endif // !QT_NO_ANIMATION + + // Immediately set the properties that are not animated. + { + QHash >::const_iterator it; + for (it = propertyAssignmentsForState.constBegin(); it != propertyAssignmentsForState.constEnd(); ++it) { + const QList &assignments = it.value(); + for (int i = 0; i < assignments.size(); ++i) { + const QPropertyAssignment &assn = assignments.at(i); + assn.object->setProperty(assn.propertyName, assn.value); + } + } + } + + // Emit polished signal for entered states that have no animated properties. + for (int i = 0; i < enteredStates.size(); ++i) { + QState *s = qobject_cast(enteredStates.at(i)); + if (s && !animationsForState.contains(s)) + QStatePrivate::get(s)->emitPolished(); + } +} + +bool QStateMachinePrivate::isFinal(const QAbstractState *s) +{ + return qobject_cast(s) != 0; +} + +bool QStateMachinePrivate::isParallel(const QAbstractState *s) +{ + const QState *ss = qobject_cast(s); + return ss && (QStatePrivate::get(ss)->childMode == QState::ParallelStates); +} + +bool QStateMachinePrivate::isCompound(const QAbstractState *s) +{ + const QState *group = qobject_cast(s); + if (!group) + return false; + return (!isParallel(group) && !QStatePrivate::get(group)->childStates().isEmpty()) + || (qobject_cast(group->parent()) != 0); +} + +bool QStateMachinePrivate::isAtomic(const QAbstractState *s) +{ + const QState *ss = qobject_cast(s); + return (ss && QStatePrivate::get(ss)->childStates().isEmpty()) + || isFinal(s); +} + + +bool QStateMachinePrivate::isDescendantOf(const QAbstractState *state, const QAbstractState *other) +{ + Q_ASSERT(state != 0); + for (QAbstractState *s = state->parentState(); s != 0; s = s->parentState()) { + if (s == other) + return true; + } + return false; +} + +QList QStateMachinePrivate::properAncestors(const QAbstractState *state, const QState *upperBound) +{ + Q_ASSERT(state != 0); + QList result; + for (QState *s = state->parentState(); s && s != upperBound; s = s->parentState()) { + result.append(s); + } + return result; +} + +bool QStateMachinePrivate::isInFinalState(QAbstractState* s) const +{ + if (isCompound(s)) { + QState *grp = qobject_cast(s); + QList lst = QStatePrivate::get(grp)->childStates(); + for (int i = 0; i < lst.size(); ++i) { + QAbstractState *cs = lst.at(i); + if (isFinal(cs) && configuration.contains(cs)) + return true; + } + return false; + } else if (isParallel(s)) { + QState *grp = qobject_cast(s); + QList lst = QStatePrivate::get(grp)->childStates(); + for (int i = 0; i < lst.size(); ++i) { + QAbstractState *cs = lst.at(i); + if (!isInFinalState(cs)) + return false; + } + return true; + } + else + return false; +} + +void QStateMachinePrivate::registerRestorable(QObject *object, const QByteArray &propertyName) +{ + RestorableId id(object, propertyName); + if (!registeredRestorables.contains(id)) + registeredRestorables.insert(id, object->property(propertyName)); +} + +QList QStateMachinePrivate::restorablesToPropertyList(const QHash &restorables) const +{ + QList result; + QHash::const_iterator it; + for (it = restorables.constBegin(); it != restorables.constEnd(); ++it) { +// qDebug() << "restorable:" << it.key().first << it.key().second << it.value(); + result.append(QPropertyAssignment(it.key().first, it.key().second, it.value(), /*explicitlySet=*/false)); + } + return result; +} + +/*! + \internal + Returns true if the variable with the given \a id has been registered for restoration. +*/ +bool QStateMachinePrivate::hasRestorable(QObject *object, const QByteArray &propertyName) const +{ + return registeredRestorables.contains(RestorableId(object, propertyName)); +} + +QVariant QStateMachinePrivate::restorableValue(QObject *object, const QByteArray &propertyName) const +{ + return registeredRestorables.value(RestorableId(object, propertyName), QVariant()); +} + + +/*! + \internal + Unregisters the variable identified by \a id +*/ +void QStateMachinePrivate::unregisterRestorable(QObject *object, const QByteArray &propertyName) +{ +// qDebug() << "unregisterRestorable(" << object << propertyName << ")"; + RestorableId id(object, propertyName); + registeredRestorables.remove(id); +} + +QAbstractState *QStateMachinePrivate::findErrorState(QAbstractState *context) +{ + // If the user sets the root state's error state to 0, we return the initial error state + if (context == 0) + return initialErrorStateForRoot; + + // Find error state recursively in parent hierarchy if not set explicitly for context state + QAbstractState *errorState = 0; + + QState *s = qobject_cast(context); + if (s) + errorState = s->errorState(); + + if (!errorState) + errorState = findErrorState(context->parentState()); + + return errorState; +} + +void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractState *currentContext) +{ + error = errorCode; + + switch (errorCode) { + case QStateMachine::NoInitialStateError: + Q_ASSERT(currentContext != 0); + + errorString = QStateMachine::tr("Missing initial state in compound state '%1'") + .arg(currentContext->objectName()); + + break; + case QStateMachine::NoDefaultStateInHistoryStateError: + Q_ASSERT(currentContext != 0); + + errorString = QStateMachine::tr("Missing default state in history state '%1'") + .arg(currentContext->objectName()); + break; + + case QStateMachine::NoCommonAncestorForTransitionError: + Q_ASSERT(currentContext != 0); + + errorString = QStateMachine::tr("No common ancestor for targets and source of transition from state '%1'") + .arg(currentContext->objectName()); + break; + default: + errorString = QStateMachine::tr("Unknown error"); + }; + + pendingErrorStates.clear(); + pendingErrorStatesForDefaultEntry.clear(); + + QAbstractState *currentErrorState = findErrorState(currentContext); + + // Avoid infinite loop if the error state itself has an error + if (currentContext == currentErrorState) { + Q_ASSERT(currentContext != initialErrorStateForRoot); // RootErrorState is broken + currentErrorState = initialErrorStateForRoot; + } + + Q_ASSERT(currentErrorState != 0); + Q_ASSERT(currentErrorState != rootState); + + QState *lca = findLCA(QList() << currentErrorState << currentContext); + addStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry); +} + +#ifndef QT_NO_ANIMATION + +QPair, QList > +QStateMachinePrivate::initializeAnimation(QAbstractAnimation *abstractAnimation, + const QPropertyAssignment &prop) +{ + QList handledAnimations; + QList localResetEndValues; + QAnimationGroup *group = qobject_cast(abstractAnimation); + if (group) { + for (int i = 0; i < group->animationCount(); ++i) { + QAbstractAnimation *animationChild = group->animationAt(i); + QPair, QList > ret; + ret = initializeAnimation(animationChild, prop); + handledAnimations << ret.first; + localResetEndValues << ret.second; + } + } else { + QPropertyAnimation *animation = qobject_cast(abstractAnimation); + if (animation != 0 + && prop.object == animation->targetObject() + && prop.propertyName == animation->propertyName()) { + + // Only change end value if it is undefined + if (!animation->endValue().isValid()) { + animation->setEndValue(prop.value); + localResetEndValues.append(animation); + } + handledAnimations.append(animation); + } + } + return qMakePair(handledAnimations, localResetEndValues); +} + +void QStateMachinePrivate::_q_animationFinished() +{ + Q_Q(QStateMachine); + QAbstractAnimation *anim = qobject_cast(q->sender()); + Q_ASSERT(anim != 0); + QObject::disconnect(anim, SIGNAL(finished()), q, SLOT(_q_animationFinished())); + if (resetAnimationEndValues.contains(anim)) { + qobject_cast(anim)->setEndValue(QVariant()); // ### generalize + resetAnimationEndValues.remove(anim); + } + + // Set the final property value. + QPropertyAssignment assn = propertyForAnimation.take(anim); + Q_ASSERT(assn.object != 0); + assn.object->setProperty(assn.propertyName, assn.value); + if (!assn.explicitlySet) + unregisterRestorable(assn.object, assn.propertyName); + + QAbstractState *state = stateForAnimation.take(anim); + Q_ASSERT(state != 0); + QHash >::iterator it; + it = animationsForState.find(state); + Q_ASSERT(it != animationsForState.end()); + QList &animations = it.value(); + animations.removeOne(anim); + if (animations.isEmpty()) { + animationsForState.erase(it); + QStatePrivate::get(qobject_cast(state))->emitPolished(); + } +} + +#endif // !QT_NO_ANIMATION + +namespace { + +class StartState : public QState +{ +public: + StartState(QState *parent) + : QState(parent) {} +protected: + void onEntry(QEvent *) {} + void onExit(QEvent *) {} +}; + +class InitialTransition : public QAbstractTransition +{ +public: + InitialTransition(QAbstractState *target) + : QAbstractTransition(QList() << target) {} +protected: + virtual bool eventTest(QEvent *) { return true; } + virtual void onTransition(QEvent *) {} +}; + +} // namespace + +void QStateMachinePrivate::_q_start() +{ + Q_Q(QStateMachine); + Q_ASSERT(state == Starting); + if (!rootState) { + state = NotRunning; + return; + } + QAbstractState *initial = rootState->initialState(); + if (initial == 0) + setError(QStateMachine::NoInitialStateError, rootState); + + configuration.clear(); + qDeleteAll(internalEventQueue); + internalEventQueue.clear(); + qDeleteAll(externalEventQueue); + externalEventQueue.clear(); + +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": starting"; +#endif + state = Running; + processingScheduled = true; // we call _q_process() below + emit q->started(); + + StartState *start = new StartState(rootState); + QAbstractTransition *initialTransition = new InitialTransition(initial); + start->addTransition(initialTransition); + QList transitions; + transitions.append(initialTransition); + QEvent nullEvent(QEvent::None); + executeTransitionContent(&nullEvent, transitions); + enterStates(&nullEvent, transitions); + applyProperties(transitions, QList() << start, + QList() << initial); + delete start; + +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": initial configuration:" << configuration; +#endif + _q_process(); +} + +void QStateMachinePrivate::_q_process() +{ + Q_Q(QStateMachine); + Q_ASSERT(state == Running); + Q_ASSERT(!processing); + processing = true; + processingScheduled = false; +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": starting the event processing loop"; +#endif + while (processing) { + if (stop) { + stop = false; + processing = false; + stopProcessingReason = Stopped; + break; + } + QSet enabledTransitions; + QEvent *e = new QEvent(QEvent::None); + enabledTransitions = selectTransitions(e); + if (enabledTransitions.isEmpty()) { + delete e; + e = 0; + } + if (enabledTransitions.isEmpty() && !internalEventQueue.isEmpty()) { + e = internalEventQueue.takeFirst(); +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": dequeued internal event" << e << "of type" << e->type(); +#endif + enabledTransitions = selectTransitions(e); + if (enabledTransitions.isEmpty()) { + delete e; + e = 0; + } + } + if (enabledTransitions.isEmpty()) { + if (externalEventQueue.isEmpty()) { + if (internalEventQueue.isEmpty()) { + processing = false; + stopProcessingReason = EventQueueEmpty; + } + } else { + e = externalEventQueue.takeFirst(); +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": dequeued external event" << e << "of type" << e->type(); +#endif + enabledTransitions = selectTransitions(e); + if (enabledTransitions.isEmpty()) { + delete e; + e = 0; + } + } + } + if (!enabledTransitions.isEmpty()) { + q->beginMicrostep(e); + microstep(e, enabledTransitions.toList()); + q->endMicrostep(e); + } +#ifdef QSTATEMACHINE_DEBUG + else { + qDebug() << q << ": no transitions enabled"; + } +#endif + delete e; + } +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": finished the event processing loop"; +#endif + switch (stopProcessingReason) { + case EventQueueEmpty: + break; + case Finished: + state = NotRunning; + unregisterAllTransitions(); + emit q->finished(); + break; + case Stopped: + state = NotRunning; + unregisterAllTransitions(); + emit q->stopped(); + break; + } +} + +void QStateMachinePrivate::scheduleProcess() +{ + if ((state != Running) || processing || processingScheduled) + return; + processingScheduled = true; + QMetaObject::invokeMethod(q_func(), "_q_process", Qt::QueuedConnection); +} + +void QStateMachinePrivate::registerTransitions(QAbstractState *state) +{ + QState *group = qobject_cast(state); + if (!group) + return; + QList transitions = QStatePrivate::get(group)->transitions(); + for (int i = 0; i < transitions.size(); ++i) { + QAbstractTransition *t = transitions.at(i); + if (QSignalTransition *st = qobject_cast(t)) { + registerSignalTransition(st); + } +#ifndef QT_NO_STATEMACHINE_EVENTFILTER + else if (QEventTransition *oet = qobject_cast(t)) { + registerEventTransition(oet); + } +#endif + } +} + +void QStateMachinePrivate::unregisterTransition(QAbstractTransition *transition) +{ + if (QSignalTransition *st = qobject_cast(transition)) { + unregisterSignalTransition(st); + } +#ifndef QT_NO_STATEMACHINE_EVENTFILTER + else if (QEventTransition *oet = qobject_cast(transition)) { + unregisterEventTransition(oet); + } +#endif +} + +static int senderSignalIndex(const QObject *sender) +{ + QObjectPrivate *d = QObjectPrivate::get(const_cast(sender)); + QMutexLocker(&d->threadData->mutex); + if (!d->currentSender) + return -1; + + // Return -1 if d->currentSender isn't in d->senders + bool found = false; + for (int i = 0; !found && i < d->senders.count(); ++i) + found = (d->senders.at(i)->sender == d->currentSender->sender); + if (!found) + return -1; + return d->currentSender->signal; +} + +void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transition) +{ + Q_Q(QStateMachine); + if (QSignalTransitionPrivate::get(transition)->signalIndex != -1) + return; // already registered + QObject *sender = QSignalTransitionPrivate::get(transition)->sender; + if (!sender) + return; + QByteArray signal = QSignalTransitionPrivate::get(transition)->signal; + if (signal.startsWith('0'+QSIGNAL_CODE)) + signal.remove(0, 1); + int signalIndex = sender->metaObject()->indexOfSignal(signal); + if (signalIndex == -1) { + qWarning("QSignalTransition: no such signal: %s::%s", + sender->metaObject()->className(), signal.constData()); + return; + } + QVector &connectedSignalIndexes = connections[sender]; + if (connectedSignalIndexes.size() <= signalIndex) + connectedSignalIndexes.resize(signalIndex+1); + if (connectedSignalIndexes.at(signalIndex) == 0) { + if (!signalEventGenerator) + signalEventGenerator = new QSignalEventGenerator(q); + bool ok = QMetaObject::connect(sender, signalIndex, signalEventGenerator, + signalEventGenerator->metaObject()->methodOffset()); + if (!ok) { +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": FAILED to add signal transition from" << transition->sourceState() + << ": ( sender =" << sender << ", signal =" << (signal.mid(1)) + << ", targets =" << transition->targetStates() << ")"; +#endif + return; + } + } + ++connectedSignalIndexes[signalIndex]; + QSignalTransitionPrivate::get(transition)->signalIndex = signalIndex; +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": added signal transition from" << transition->sourceState() + << ": ( sender =" << sender << ", signal =" << (signal.mid(1)) + << ", targets =" << transition->targetStates() << ")"; +#endif +} + +void QStateMachinePrivate::unregisterSignalTransition(QSignalTransition *transition) +{ + int signalIndex = QSignalTransitionPrivate::get(transition)->signalIndex; + if (signalIndex == -1) + return; // not registered + QSignalTransitionPrivate::get(transition)->signalIndex = -1; + const QObject *sender = QSignalTransitionPrivate::get(transition)->sender; + QVector &connectedSignalIndexes = connections[sender]; + Q_ASSERT(connectedSignalIndexes.size() > signalIndex); + Q_ASSERT(connectedSignalIndexes.at(signalIndex) != 0); + if (--connectedSignalIndexes[signalIndex] == 0) { + Q_ASSERT(signalEventGenerator != 0); + QMetaObject::disconnect(sender, signalIndex, signalEventGenerator, + signalEventGenerator->metaObject()->methodOffset()); + int sum = 0; + for (int i = 0; i < connectedSignalIndexes.size(); ++i) + sum += connectedSignalIndexes.at(i); + if (sum == 0) + connections.remove(sender); + } +} + +void QStateMachinePrivate::unregisterAllTransitions() +{ + { + QList transitions = qFindChildren(rootState); + for (int i = 0; i < transitions.size(); ++i) + unregisterSignalTransition(transitions.at(i)); + } + { + QList transitions = qFindChildren(rootState); + for (int i = 0; i < transitions.size(); ++i) + unregisterEventTransition(transitions.at(i)); + } +} + +#ifndef QT_NO_STATEMACHINE_EVENTFILTER +void QStateMachinePrivate::registerEventTransition(QEventTransition *transition) +{ + Q_Q(QStateMachine); + if (QEventTransitionPrivate::get(transition)->registered) + return; + if (transition->eventType() >= QEvent::User) { + qWarning("QObject event transitions are not supported for custom types"); + return; + } + QObject *object = QEventTransitionPrivate::get(transition)->object; + if (!object) + return; + QObjectPrivate *od = QObjectPrivate::get(object); + if (!od->eventFilters.contains(q)) + object->installEventFilter(q); + ++qobjectEvents[object][transition->eventType()]; + QEventTransitionPrivate::get(transition)->registered = true; +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q << ": added event transition from" << transition->sourceState() + << ": ( object =" << object << ", event =" << transition->eventType() + << ", targets =" << transition->targetStates() << ")"; +#endif +} + +void QStateMachinePrivate::unregisterEventTransition(QEventTransition *transition) +{ + Q_Q(QStateMachine); + if (!QEventTransitionPrivate::get(transition)->registered) + return; + QObject *object = QEventTransitionPrivate::get(transition)->object; + QHash &events = qobjectEvents[object]; + Q_ASSERT(events.value(transition->eventType()) > 0); + if (--events[transition->eventType()] == 0) { + events.remove(transition->eventType()); + int sum = 0; + QHash::const_iterator it; + for (it = events.constBegin(); it != events.constEnd(); ++it) + sum += it.value(); + if (sum == 0) { + qobjectEvents.remove(object); + object->removeEventFilter(q); + } + } + QEventTransitionPrivate::get(transition)->registered = false; +} +#endif + +void QStateMachinePrivate::handleTransitionSignal(const QObject *sender, int signalIndex, + void **argv) +{ + const QVector &connectedSignalIndexes = connections[sender]; + Q_ASSERT(connectedSignalIndexes.at(signalIndex) != 0); + const QMetaObject *meta = sender->metaObject(); + QMetaMethod method = meta->method(signalIndex); + QList parameterTypes = method.parameterTypes(); + int argc = parameterTypes.count(); + QList vargs; + for (int i = 0; i < argc; ++i) { + int type = QMetaType::type(parameterTypes.at(i)); + vargs.append(QVariant(type, argv[i+1])); + } + +#ifdef QSTATEMACHINE_DEBUG + qDebug() << q_func() << ": sending signal event ( sender =" << sender + << ", signal =" << sender->metaObject()->method(signalIndex).signature() << ")"; +#endif + internalEventQueue.append(new QSignalEvent(sender, signalIndex, vargs)); + scheduleProcess(); +} + +/*! + Constructs a new state machine with the given \a parent. +*/ +QStateMachine::QStateMachine(QObject *parent) + : QObject(*new QStateMachinePrivate, parent) +{ +} + +/*! + \internal +*/ +QStateMachine::QStateMachine(QStateMachinePrivate &dd, QObject *parent) + : QObject(dd, parent) +{ +} + +/*! + Destroys this state machine. +*/ +QStateMachine::~QStateMachine() +{ +} + +namespace { + +class RootErrorState : public QAbstractState +{ +public: + RootErrorState(QState *parent) + : QAbstractState(parent) + { + setObjectName(QString::fromLatin1("DefaultErrorState")); + } + + void onEntry(QEvent *) + { + QAbstractStatePrivate *d = QAbstractStatePrivate::get(this); + QStateMachine *machine = d->machine(); + + qWarning("Unrecoverable error detected in running state machine: %s", + qPrintable(machine->errorString())); + } + + void onExit(QEvent *) {} +}; + +class RootState : public QState +{ +public: + RootState(QState *parent) + : QState(parent) + { + } + + void onEntry(QEvent *) {} + void onExit(QEvent *) {} +}; + +} // namespace + +/*! + Returns this state machine's root state. +*/ +QState *QStateMachine::rootState() const +{ + Q_D(const QStateMachine); + if (!d->rootState) { + const_cast(d)->rootState = new RootState(0); + const_cast(d)->initialErrorStateForRoot = new RootErrorState(d->rootState); + d->rootState->setParent(const_cast(this)); + d->rootState->setErrorState(d->initialErrorStateForRoot); + } + return d->rootState; +} + +/*! + Returns the error state of the state machine's root state. + + \sa QState::errorState() +*/ +QAbstractState *QStateMachine::errorState() const +{ + return rootState()->errorState(); +} + +/*! + Sets the error state of this state machine's root state to be \a state. When a running state + machine encounters an error which puts it in an undefined state, it will enter an error state + based on the context of the error that occurred. It will enter this state regardless of what + is currently in the event queue. + + If the erroneous state has an error state set, this will be entered by the machine. If no error + state has been set, the state machine will search the parent hierarchy recursively for an + error state. The error state of the root state can thus be seen as a global error state that + applies for the states for which a more specific error state has not been set. + + Before entering the error state, the state machine will set the error code returned by error() and + error message returned by errorString(). + + The default error state will print a warning to the console containing the information returned by + errorString(). By setting a new error state on either the state machine itself, or on specific + states, you can fine tune error handling in the state machine. + + If the root state's error state is set to 0, or if the error state selected by the machine itself + contains an error, the default error state will be used. + + \sa QState::setErrorState(), rootState() +*/ +void QStateMachine::setErrorState(QAbstractState *state) +{ + rootState()->setErrorState(state); +} + +/*! \enum QStateMachine::Error + + This enum type defines errors that can occur in the state machine at run time. When the state + machine encounters an unrecoverable error at run time, it will set the error code returned + by error(), the error message returned by errorString(), and enter an error state based on + the context of the error. + + \value NoError No error has occurred. + \value NoInitialStateError The machine has entered a QState with children which does not have an + initial state set. The context of this error is the state which is missing an initial + state. + \value NoDefaultStateInHistoryStateError The machine has entered a QHistoryState which does not have + a default state set. The context of this error is the QHistoryState which is missing a + default state. + \value NoCommonAncestorForTransitionError The machine has selected a transition whose source + and targets are not part of the same tree of states, and thus are not part of the same + state machine. Commonly, this could mean that one of the states has not been given + any parent or added to any machine. The context of this error is the source state of + the transition. + + \sa setErrorState() +*/ + +/*! + \enum QStateMachine::RestorePolicy + + This enum specifies the restore policy type. The restore policy + takes effect when the machine enters a state which sets one or more + properties. If the restore policy is set to RestoreProperties, + the state machine will save the original value of the property before the + new value is set. + + Later, when the machine either enters a state which does not set + a value for the given property, the property will automatically be restored + to its initial value. + + Only one initial value will be saved for any given property. If a value for a property has + already been saved by the state machine, it will not be overwritten until the property has been + successfully restored. + + \value DoNotRestoreProperties The state machine should not save the initial values of properties + and restore them later. + \value RestoreProperties The state machine should save the initial values of properties + and restore them later. + + \sa QStateMachine::globalRestorePolicy QState::assignProperty() +*/ + + +/*! + Returns the error code of the last error that occurred in the state machine. +*/ +QStateMachine::Error QStateMachine::error() const +{ + Q_D(const QStateMachine); + return d->error; +} + +/*! + Returns the error string of the last error that occurred in the state machine. +*/ +QString QStateMachine::errorString() const +{ + Q_D(const QStateMachine); + return d->errorString; +} + +/*! + Clears the error string and error code of the state machine. +*/ +void QStateMachine::clearError() +{ + Q_D(QStateMachine); + d->errorString.clear(); + d->error = NoError; +} + +/*! + Returns the restore policy of the state machine. + + \sa setGlobalRestorePolicy() +*/ +QStateMachine::RestorePolicy QStateMachine::globalRestorePolicy() const +{ + Q_D(const QStateMachine); + return d->globalRestorePolicy; +} + +/*! + Sets the restore policy of the state machine to \a restorePolicy. The default + restore policy is QAbstractState::DoNotRestoreProperties. + + \sa globalRestorePolicy() +*/ +void QStateMachine::setGlobalRestorePolicy(QStateMachine::RestorePolicy restorePolicy) +{ + Q_D(QStateMachine); + d->globalRestorePolicy = restorePolicy; +} + +/*! + Returns this state machine's initial state, or 0 if no initial state has + been set. +*/ +QAbstractState *QStateMachine::initialState() const +{ + Q_D(const QStateMachine); + if (!d->rootState) + return 0; + return d->rootState->initialState(); +} + +/*! + Sets this state machine's initial \a state. +*/ +void QStateMachine::setInitialState(QAbstractState *state) +{ + Q_D(QStateMachine); + if (!d->rootState) { + if (!state) + return; + rootState()->setInitialState(state); + } + d->rootState->setInitialState(state); +} + +/*! + Adds the given \a state to this state machine. The state becomes a top-level + state (i.e. a child of the rootState()). + + If the state is already in a different machine, it will first be removed + from its old machine, and then added to this machine. + + \sa removeState(), rootState(), setInitialState() +*/ +void QStateMachine::addState(QAbstractState *state) +{ + if (!state) { + qWarning("QStateMachine::addState: cannot add null state"); + return; + } + if (QAbstractStatePrivate::get(state)->machine() == this) { + qWarning("QStateMachine::addState: state has already been added to this machine"); + return; + } + state->setParent(rootState()); +} + +/*! + Removes the given \a state from this state machine. The state machine + releases ownership of the state. + + \sa addState() +*/ +void QStateMachine::removeState(QAbstractState *state) +{ + if (!state) { + qWarning("QStateMachine::removeState: cannot remove null state"); + return; + } + if (QAbstractStatePrivate::get(state)->machine() != this) { + qWarning("QStateMachine::removeState: state %p's machine (%p)" + " is different from this machine (%p)", + state, QAbstractStatePrivate::get(state)->machine(), this); + return; + } + state->setParent(0); +} + +/*! + Returns whether this state machine is running. + + start(), stop() +*/ +bool QStateMachine::isRunning() const +{ + Q_D(const QStateMachine); + return (d->state == QStateMachinePrivate::Running); +} + +/*! + Starts this state machine. The machine will reset its configuration and + transition to the initial state. When a final top-level state (QFinalState) + is entered, the machine will emit the finished() signal. + + \sa started(), finished(), stop(), initialState() +*/ +void QStateMachine::start() +{ + Q_D(QStateMachine); + + if (rootState()->initialState() == 0) { + qWarning("QStateMachine::start: No initial state set for machine. Refusing to start."); + return; + } + + switch (d->state) { + case QStateMachinePrivate::NotRunning: + d->state = QStateMachinePrivate::Starting; + QMetaObject::invokeMethod(this, "_q_start", Qt::QueuedConnection); + break; + case QStateMachinePrivate::Starting: + break; + case QStateMachinePrivate::Running: + qWarning("QStateMachine::start(): already running"); + break; + } +} + +/*! + Stops this state machine. The state machine will stop processing events and + then emit the stopped() signal. + + \sa stopped(), start() +*/ +void QStateMachine::stop() +{ + Q_D(QStateMachine); + switch (d->state) { + case QStateMachinePrivate::NotRunning: + break; + case QStateMachinePrivate::Starting: + // the machine will exit as soon as it enters the event processing loop + d->stop = true; + break; + case QStateMachinePrivate::Running: + d->stop = true; + d->scheduleProcess(); + break; + } +} + +/*! + Posts the given \a event for processing by this state machine, with a delay + of \a delay milliseconds. + + This function returns immediately. The event is added to the state machine's + event queue. Events are processed in the order posted. The state machine + takes ownership of the event and deletes it once it has been processed. + + You can only post events when the state machine is running. +*/ +void QStateMachine::postEvent(QEvent *event, int delay) +{ + Q_D(QStateMachine); + if (d->state != QStateMachinePrivate::Running) { + qWarning("QStateMachine::postEvent: cannot post event when the state machine is not running"); + return; + } +#ifdef QSTATEMACHINE_DEBUG + qDebug() << this << ": posting external event" << event << "with delay" << delay; +#endif + if (delay) { + int tid = startTimer(delay); + d->delayedEvents[tid] = event; + } else { + d->externalEventQueue.append(event); + d->scheduleProcess(); + } +} + +/*! + \internal + + Posts the given internal \a event for processing by this state machine. +*/ +void QStateMachine::postInternalEvent(QEvent *event) +{ + Q_D(QStateMachine); +#ifdef QSTATEMACHINE_DEBUG + qDebug() << this << ": posting internal event" << event; +#endif + d->internalEventQueue.append(event); + d->scheduleProcess(); +} + +/*! + \internal + + Returns the maximal consistent set of states (including parallel and final + states) that this state machine is currently in. If a state \c s is in the + configuration, it is always the case that the parent of \c s is also in + c. Note, however, that the rootState() is not an explicit member of the + configuration. +*/ +QSet QStateMachine::configuration() const +{ + Q_D(const QStateMachine); + return d->configuration; +} + +/*! + \fn QStateMachine::started() + + This signal is emitted when the state machine has entered its initial state + (QStateMachine::initialState). + + \sa QStateMachine::finished(), QStateMachine::start() +*/ + +/*! + \fn QStateMachine::finished() + + This signal is emitted when the state machine has reached a top-level final + state (QFinalState). + + \sa QStateMachine::started() +*/ + +/*! + \fn QStateMachine::stopped() + + This signal is emitted when the state machine has stopped. + + \sa QStateMachine::stop(), QStateMachine::finished() +*/ + +/*! + \reimp +*/ +bool QStateMachine::event(QEvent *e) +{ + Q_D(QStateMachine); + if (e->type() == QEvent::Timer) { + QTimerEvent *te = static_cast(e); + int tid = te->timerId(); + if (d->delayedEvents.contains(tid)) { + killTimer(tid); + QEvent *ee = d->delayedEvents.take(tid); + d->externalEventQueue.append(ee); + d->scheduleProcess(); + return true; + } + } else if (e->type() == QEvent::ChildAdded) { + QChildEvent *ce = static_cast(e); + if (QAbstractState *state = qobject_cast(ce->child())) { + if (state != rootState()) { + state->setParent(rootState()); + return true; + } + } + } + return QObject::event(e); +} + +#ifndef QT_NO_STATEMACHINE_EVENTFILTER +/*! + \reimp +*/ +bool QStateMachine::eventFilter(QObject *watched, QEvent *event) +{ + Q_D(QStateMachine); + Q_ASSERT(d->qobjectEvents.contains(watched)); + if (d->qobjectEvents[watched].contains(event->type())) + postEvent(new QWrappedEvent(watched, d->handler->cloneEvent(event))); + return false; +} +#endif + +/*! + \internal + + This function is called when the state machine is about to select + transitions based on the given \a event. + + The default implementation does nothing. +*/ +void QStateMachine::beginSelectTransitions(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \internal + + This function is called when the state machine has finished selecting + transitions based on the given \a event. + + The default implementation does nothing. +*/ +void QStateMachine::endSelectTransitions(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \internal + + This function is called when the state machine is about to do a microstep. + + The default implementation does nothing. +*/ +void QStateMachine::beginMicrostep(QEvent *event) +{ + Q_UNUSED(event); +} + +/*! + \internal + + This function is called when the state machine has finished doing a + microstep. + + The default implementation does nothing. +*/ +void QStateMachine::endMicrostep(QEvent *event) +{ + Q_UNUSED(event); +} + +#ifndef QT_NO_ANIMATION + +/*! + Returns whether animations are enabled for this state machine. +*/ +bool QStateMachine::animationsEnabled() const +{ + Q_D(const QStateMachine); + return d->animationsEnabled; +} + +/*! + Sets whether animations are \a enabled for this state machine. +*/ +void QStateMachine::setAnimationsEnabled(bool enabled) +{ + Q_D(QStateMachine); + d->animationsEnabled = enabled; +} + +/*! + Adds a default \a animation to be considered for any transition. +*/ +void QStateMachine::addDefaultAnimation(QAbstractAnimation *animation) +{ + Q_D(QStateMachine); + d->defaultAnimations.append(animation); +} + +/*! + Returns the list of default animations that will be considered for any transition. +*/ +QList QStateMachine::defaultAnimations() const +{ + Q_D(const QStateMachine); + return d->defaultAnimations; +} + +/*! + Removes \a animation from the list of default animations. +*/ +void QStateMachine::removeDefaultAnimation(QAbstractAnimation *animation) +{ + Q_D(QStateMachine); + d->defaultAnimations.removeAll(animation); +} + +#endif // QT_NO_ANIMATION + + +static const uint qt_meta_data_QSignalEventGenerator[] = { + + // content: + 2, // revision + 0, // classname + 0, 0, // classinfo + 1, 12, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + + // slots: signature, parameters, type, tag, flags + 23, 22, 22, 22, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_QSignalEventGenerator[] = { + "QSignalEventGenerator\0\0execute()\0" +}; + +const QMetaObject QSignalEventGenerator::staticMetaObject = { + { &QObject::staticMetaObject, qt_meta_stringdata_QSignalEventGenerator, + qt_meta_data_QSignalEventGenerator, 0 } +}; + +const QMetaObject *QSignalEventGenerator::metaObject() const +{ + return &staticMetaObject; +} + +void *QSignalEventGenerator::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_QSignalEventGenerator)) + return static_cast(const_cast< QSignalEventGenerator*>(this)); + return QObject::qt_metacast(_clname); +} + +int QSignalEventGenerator::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + switch (_id) { + case 0: { +// ### in Qt 4.6 we can use QObject::senderSignalIndex() + int signalIndex = senderSignalIndex(this); + Q_ASSERT(signalIndex != -1); + QStateMachine *machine = qobject_cast(parent()); + QStateMachinePrivate::get(machine)->handleTransitionSignal(sender(), signalIndex, _a); + break; + } + default: ; + } + _id -= 1; + } + return _id; +} + +QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent) + : QObject(parent) +{ +} + +/*! + \class QSignalEvent + + \brief The QSignalEvent class represents a Qt signal event. + + \since 4.6 + \ingroup statemachine + + A signal event is generated by a QStateMachine in response to a Qt + signal. The QSignalTransition class provides a transition associated with a + signal event. QSignalEvent is part of \l{The State Machine Framework}. + + The sender() function returns the object that generated the signal. The + signalIndex() function returns the index of the signal. The arguments() + function returns the arguments of the signal. + + \sa QSignalTransition +*/ + +/*! + \internal + + Constructs a new QSignalEvent object with the given \a sender, \a + signalIndex and \a arguments. +*/ +QSignalEvent::QSignalEvent(const QObject *sender, int signalIndex, + const QList &arguments) + : QEvent(QEvent::Signal), m_sender(sender), + m_signalIndex(signalIndex), m_arguments(arguments) +{ +} + +/*! + Destroys this QSignalEvent. +*/ +QSignalEvent::~QSignalEvent() +{ +} + +/*! + \fn QSignalEvent::sender() const + + Returns the object that emitted the signal. + + \sa QObject::sender() +*/ + +/*! + \fn QSignalEvent::signalIndex() const + + Returns the index of the signal. + + \sa QMetaObject::indexOfSignal(), QMetaObject::method() +*/ + +/*! + \fn QSignalEvent::arguments() const + + Returns the arguments of the signal. +*/ + + +/*! + \class QWrappedEvent + + \brief The QWrappedEvent class holds a clone of an event associated with a QObject. + + \since 4.6 + \ingroup statemachine + + A wrapped event is generated by a QStateMachine in response to a Qt + event. The QEventTransition class provides a transition associated with a + such an event. QWrappedEvent is part of \l{The State Machine Framework}. + + The object() function returns the object that generated the event. The + event() function returns a clone of the original event. + + \sa QEventTransition +*/ + +/*! + \internal + + Constructs a new QWrappedEvent object with the given \a object + and \a event. +*/ +QWrappedEvent::QWrappedEvent(QObject *object, QEvent *event) + : QEvent(QEvent::Wrapped), m_object(object), m_event(event) +{ +} + +/*! + Destroys this QWrappedEvent. +*/ +QWrappedEvent::~QWrappedEvent() +{ +} + +/*! + \fn QWrappedEvent::object() const + + Returns the object that the event is associated with. +*/ + +/*! + \fn QWrappedEvent::event() const + + Returns a clone of the original event. +*/ + +QT_END_NAMESPACE + +#include "moc_qstatemachine.cpp" diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h new file mode 100644 index 0000000..2a98a9a --- /dev/null +++ b/src/corelib/statemachine/qstatemachine.h @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTATEMACHINE_H +#define QSTATEMACHINE_H + +#include + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QEvent; +class QAbstractState; +class QState; + +class QStateMachinePrivate; +class QAbstractAnimation; +class QAbstractState; +class Q_CORE_EXPORT QStateMachine : public QObject +{ + Q_OBJECT + Q_PROPERTY(QState* rootState READ rootState) + Q_PROPERTY(QAbstractState* initialState READ initialState WRITE setInitialState) + Q_PROPERTY(QAbstractState* errorState READ errorState WRITE setErrorState) + Q_PROPERTY(QString errorString READ errorString) + Q_PROPERTY(RestorePolicy globalRestorePolicy READ globalRestorePolicy WRITE setGlobalRestorePolicy) + Q_ENUMS(RestorePolicy) +#ifndef QT_NO_ANIMATION + Q_PROPERTY(bool animationsEnabled READ animationsEnabled WRITE setAnimationsEnabled) +#endif +public: + enum RestorePolicy { + DoNotRestoreProperties, + RestoreProperties + }; + + enum Error { + NoError, + NoInitialStateError, + NoDefaultStateInHistoryStateError, + NoCommonAncestorForTransitionError + }; + + QStateMachine(QObject *parent = 0); + ~QStateMachine(); + + void addState(QAbstractState *state); + void removeState(QAbstractState *state); + + QState *rootState() const; + + QAbstractState *initialState() const; + void setInitialState(QAbstractState *state); + + QAbstractState *errorState() const; + void setErrorState(QAbstractState *state); + + Error error() const; + QString errorString() const; + void clearError(); + + bool isRunning() const; + +#ifndef QT_NO_ANIMATION + bool animationsEnabled() const; + void setAnimationsEnabled(bool enabled); + + void addDefaultAnimation(QAbstractAnimation *animation); + QList defaultAnimations() const; + void removeDefaultAnimation(QAbstractAnimation *animation); +#endif // QT_NO_ANIMATION + + QStateMachine::RestorePolicy globalRestorePolicy() const; + void setGlobalRestorePolicy(QStateMachine::RestorePolicy restorePolicy); + + void postEvent(QEvent *event, int delay = 0); + + QSet configuration() const; + +#ifndef QT_NO_STATEMACHINE_EVENTFILTER + bool eventFilter(QObject *watched, QEvent *event); +#endif + +public Q_SLOTS: + void start(); + void stop(); + +Q_SIGNALS: + void started(); + void stopped(); + void finished(); + +protected: + void postInternalEvent(QEvent *event); + + virtual void beginSelectTransitions(QEvent *event); + virtual void endSelectTransitions(QEvent *event); + + virtual void beginMicrostep(QEvent *event); + virtual void endMicrostep(QEvent *event); + + bool event(QEvent *e); + +protected: + QStateMachine(QStateMachinePrivate &dd, QObject *parent); + +private: + Q_DISABLE_COPY(QStateMachine) + Q_DECLARE_PRIVATE(QStateMachine) + Q_PRIVATE_SLOT(d_func(), void _q_start()) + Q_PRIVATE_SLOT(d_func(), void _q_process()) +#ifndef QT_NO_ANIMATION + Q_PRIVATE_SLOT(d_func(), void _q_animationFinished()) +#endif +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h new file mode 100644 index 0000000..dfa5575 --- /dev/null +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTATEMACHINE_P_H +#define QSTATEMACHINE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include +#include +#include +#include + +#include "qstate.h" +#include "qstate_p.h" + +QT_BEGIN_NAMESPACE + +class QEvent; +#ifndef QT_NO_STATEMACHINE_EVENTFILTER +class QEventTransition; +#endif +class QSignalEventGenerator; +class QSignalTransition; +class QAbstractState; +class QAbstractTransition; +class QState; + +#ifndef QT_NO_ANIMATION +class QAbstractAnimation; +#endif + +class QStateMachine; +class Q_CORE_EXPORT QStateMachinePrivate + : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QStateMachine) +public: + enum State { + NotRunning, + Starting, + Running + }; + enum StopProcessingReason { + EventQueueEmpty, + Finished, + Stopped + }; + + QStateMachinePrivate(); + ~QStateMachinePrivate(); + + static QStateMachinePrivate *get(QStateMachine *q); + + static QState *findLCA(const QList &states); + + static bool stateEntryLessThan(QAbstractState *s1, QAbstractState *s2); + static bool stateExitLessThan(QAbstractState *s1, QAbstractState *s2); + + QAbstractState *findErrorState(QAbstractState *context); + void setError(QStateMachine::Error error, QAbstractState *currentContext); + + // private slots + void _q_start(); + void _q_process(); +#ifndef QT_NO_ANIMATION + void _q_animationFinished(); +#endif + + void microstep(QEvent *event, const QList &transitionList); + bool isPreempted(const QAbstractState *s, const QSet &transitions) const; + QSet selectTransitions(QEvent *event) const; + QList exitStates(QEvent *event, const QList &transitionList); + void executeTransitionContent(QEvent *event, const QList &transitionList); + QList enterStates(QEvent *event, const QList &enabledTransitions); + void addStatesToEnter(QAbstractState *s, QState *root, + QSet &statesToEnter, + QSet &statesForDefaultEntry); + + void applyProperties(const QList &transitionList, + const QList &exitedStates, + const QList &enteredStates); + + bool isInFinalState(QAbstractState *s) const; + static bool isFinal(const QAbstractState *s); + static bool isParallel(const QAbstractState *s); + static bool isCompound(const QAbstractState *s); + static bool isAtomic(const QAbstractState *s); + static bool isDescendantOf(const QAbstractState *s, const QAbstractState *other); + static QList properAncestors(const QAbstractState *s, const QState *upperBound); + + void registerTransitions(QAbstractState *state); + void registerSignalTransition(QSignalTransition *transition); + void unregisterSignalTransition(QSignalTransition *transition); +#ifndef QT_NO_STATEMACHINE_EVENTFILTER + void registerEventTransition(QEventTransition *transition); + void unregisterEventTransition(QEventTransition *transition); +#endif + void unregisterTransition(QAbstractTransition *transition); + void unregisterAllTransitions(); + void handleTransitionSignal(const QObject *sender, int signalIndex, + void **args); + void scheduleProcess(); + + typedef QPair RestorableId; + QHash registeredRestorables; + void registerRestorable(QObject *object, const QByteArray &propertyName); + void unregisterRestorable(QObject *object, const QByteArray &propertyName); + bool hasRestorable(QObject *object, const QByteArray &propertyName) const; + QVariant restorableValue(QObject *object, const QByteArray &propertyName) const; + QList restorablesToPropertyList(const QHash &restorables) const; + + State state; + bool processing; + bool processingScheduled; + bool stop; + StopProcessingReason stopProcessingReason; + QState *rootState; + QSet configuration; + QList internalEventQueue; + QList externalEventQueue; + + QStateMachine::Error error; + QStateMachine::RestorePolicy globalRestorePolicy; + + QString errorString; + QSet pendingErrorStates; + QSet pendingErrorStatesForDefaultEntry; + QAbstractState *initialErrorStateForRoot; + +#ifndef QT_NO_ANIMATION + bool animationsEnabled; + + QPair, QList > + initializeAnimation(QAbstractAnimation *abstractAnimation, + const QPropertyAssignment &prop); + + QHash > animationsForState; + QHash propertyForAnimation; + QHash stateForAnimation; + QSet resetAnimationEndValues; + + QList defaultAnimations; + QMultiHash defaultAnimationsForSource; + QMultiHash defaultAnimationsForTarget; + +#endif // QT_NO_ANIMATION + + QSignalEventGenerator *signalEventGenerator; + + QHash > connections; +#ifndef QT_NO_STATEMACHINE_EVENTFILTER + QHash > qobjectEvents; +#endif + QHash delayedEvents; + + typedef QEvent* (*f_cloneEvent)(QEvent*); + struct Handler { + f_cloneEvent cloneEvent; + }; + + static const Handler *handler; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/statemachine/qwrappedevent.h b/src/corelib/statemachine/qwrappedevent.h new file mode 100644 index 0000000..b01c608 --- /dev/null +++ b/src/corelib/statemachine/qwrappedevent.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWRAPPEDEVENT_H +#define QWRAPPEDEVENT_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QObject; + +class Q_CORE_EXPORT QWrappedEvent : public QEvent +{ +public: + QWrappedEvent(QObject *object, QEvent *event); + ~QWrappedEvent(); + + inline QObject *object() const { return m_object; } + inline QEvent *event() const { return m_event; } + +private: + QObject *m_object; + QEvent *m_event; + +private: + Q_DISABLE_COPY(QWrappedEvent) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/statemachine/statemachine.pri b/src/corelib/statemachine/statemachine.pri new file mode 100644 index 0000000..5b19bc1 --- /dev/null +++ b/src/corelib/statemachine/statemachine.pri @@ -0,0 +1,30 @@ +HEADERS += $$PWD/qstatemachine.h \ + $$PWD/qstatemachine_p.h \ + $$PWD/qsignaleventgenerator_p.h \ + $$PWD/qabstractstate.h \ + $$PWD/qabstractstate_p.h \ + $$PWD/qstate.h \ + $$PWD/qstate_p.h \ + $$PWD/qfinalstate.h \ + $$PWD/qhistorystate.h \ + $$PWD/qhistorystate_p.h \ + $$PWD/qabstracttransition.h \ + $$PWD/qabstracttransition_p.h \ + $$PWD/qsignalevent.h \ + $$PWD/qsignaltransition.h \ + $$PWD/qsignaltransition_p.h + +SOURCES += $$PWD/qstatemachine.cpp \ + $$PWD/qabstractstate.cpp \ + $$PWD/qstate.cpp \ + $$PWD/qfinalstate.cpp \ + $$PWD/qhistorystate.cpp \ + $$PWD/qabstracttransition.cpp \ + $$PWD/qsignaltransition.cpp + +!contains(DEFINES, QT_NO_STATEMACHINE_EVENTFILTER) { +HEADERS += $$PWD/qwrappedevent.h \ + $$PWD/qeventtransition.h \ + $$PWD/qeventtransition_p.h +SOURCES += $$PWD/qeventtransition.cpp +} diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp new file mode 100644 index 0000000..2b027fc --- /dev/null +++ b/src/corelib/tools/qeasingcurve.cpp @@ -0,0 +1,846 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + +| *property* | *Used for type* | +| period | QEasingCurve::{In,Out,InOut,OutIn}Elastic | +| amplitude | QEasingCurve::{In,Out,InOut,OutIn}Bounce, QEasingCurve::{In,Out,InOut,OutIn}Elastic | +| overshoot | QEasingCurve::{In,Out,InOut,OutIn}Back | + +*/ + + + + +/*! + \class QEasingCurve + \since 4.6 + \ingroup animation + \brief The QEasingCurve class provides easing curves for controlling animation. + + Easing curves describe a function that controls how the speed of the interpolation + between 0 and 1 should be. Easing curves allow transitions from + one value to another to appear more natural than a simple constant speed would allow. + The QEasingCurve class is usually used in conjunction with the QAnimation class, + but can be used on its own. + + To calculate the speed of the interpolation, the easing curve provides the function + valueForProgress(), where the \a progress argument specifies the progress of the + interpolation: 0 is the start value of the interpolation, 1 is the end value of the + interpolation. The returned value is the effective progress of the interpolation. + If the returned value is the same as the input value for all input values the easing + curve is a linear curve. This is the default behaviour. + + For example, + \code + QEasingCurve easing(QEasingCurve::InOutQuad); + + for(qreal t = 0.0; t < 1.0; t+=0.1) + qWarning() << "Effective progress" << t << " is + << easing.valueForProgress(t); + \endcode + will print the effective progress of the interpolation between 0 and 1. + + When using a QAnimation, the easing curve will be used to control the + progress of the interpolation between startValue and endValue: + \code + QAnimation animation; + animation.setStartValue(0); + animation.setEndValue(1000); + animation.setDuration(1000); + animation.setEasingCurve(QEasingCurve::InOutQuad); + \endcode + */ + +/*! + \enum QEasingCurve::Type + + The type of easing curve. + + \value Linear \inlineimage qeasingcurve-linear.png + \br + Easing equation function for a simple linear tweening, + with no easing. + \value InQuad \inlineimage qeasingcurve-inquad.png + \br + Easing equation function for a quadratic (t^2) easing + in: accelerating from zero velocity. + \value OutQuad \inlineimage qeasingcurve-outquad.png + \br + Easing equation function for a quadratic (t^2) easing + out: decelerating to zero velocity. + \value InOutQuad \inlineimage qeasingcurve-inoutquad.png + \br + Easing equation function for a quadratic (t^2) easing + in/out: acceleration until halfway, then deceleration. + \value OutInQuad \inlineimage qeasingcurve-outinquad.png + \br + Easing equation function for a quadratic (t^2) easing + out/in: deceleration until halfway, then acceleration. + \value InCubic \inlineimage qeasingcurve-incubic.png + \br + Easing equation function for a cubic (t^3) easing + in: accelerating from zero velocity. + \value OutCubic \inlineimage qeasingcurve-outcubic.png + \br + Easing equation function for a cubic (t^3) easing + out: decelerating from zero velocity. + \value InOutCubic \inlineimage qeasingcurve-inoutcubic.png + \br + Easing equation function for a cubic (t^3) easing + in/out: acceleration until halfway, then deceleration. + \value OutInCubic \inlineimage qeasingcurve-outincubic.png + \br + Easing equation function for a cubic (t^3) easing + out/in: deceleration until halfway, then acceleration. + \value InQuart \inlineimage qeasingcurve-inquart.png + \br + Easing equation function for a quartic (t^4) easing + in: accelerating from zero velocity. + \value OutQuart \inlineimage qeasingcurve-outquart.png + \br + Easing equation function for a quartic (t^4) easing + out: decelerating from zero velocity. + \value InOutQuart \inlineimage qeasingcurve-inoutquart.png + \br + Easing equation function for a quartic (t^4) easing + in/out: acceleration until halfway, then deceleration. + \value OutInQuart \inlineimage qeasingcurve-outinquart.png + \br + Easing equation function for a quartic (t^4) easing + out/in: deceleration until halfway, then acceleration. + \value InQuint \inlineimage qeasingcurve-inquint.png + \br + Easing equation function for a quintic (t^5) easing + in: accelerating from zero velocity. + \value OutQuint \inlineimage qeasingcurve-outquint.png + \br + Easing equation function for a quintic (t^5) easing + out: decelerating from zero velocity. + \value InOutQuint \inlineimage qeasingcurve-inoutquint.png + \br + Easing equation function for a quintic (t^5) easing + in/out: acceleration until halfway, then deceleration. + \value OutInQuint \inlineimage qeasingcurve-outinquint.png + \br + Easing equation function for a quintic (t^5) easing + out/in: deceleration until halfway, then acceleration. + \value InSine \inlineimage qeasingcurve-insine.png + \br + Easing equation function for a sinusoidal (sin(t)) easing + in: accelerating from zero velocity. + \value OutSine \inlineimage qeasingcurve-outsine.png + \br + Easing equation function for a sinusoidal (sin(t)) easing + out: decelerating from zero velocity. + \value InOutSine \inlineimage qeasingcurve-inoutsine.png + \br + Easing equation function for a sinusoidal (sin(t)) easing + in/out: acceleration until halfway, then deceleration. + \value OutInSine \inlineimage qeasingcurve-outinsine.png + \br + Easing equation function for a sinusoidal (sin(t)) easing + out/in: deceleration until halfway, then acceleration. + \value InExpo \inlineimage qeasingcurve-inexpo.png + \br + Easing equation function for an exponential (2^t) easing + in: accelerating from zero velocity. + \value OutExpo \inlineimage qeasingcurve-outexpo.png + \br + Easing equation function for an exponential (2^t) easing + out: decelerating from zero velocity. + \value InOutExpo \inlineimage qeasingcurve-inoutexpo.png + \br + Easing equation function for an exponential (2^t) easing + in/out: acceleration until halfway, then deceleration. + \value OutInExpo \inlineimage qeasingcurve-outinexpo.png + \br + Easing equation function for an exponential (2^t) easing + out/in: deceleration until halfway, then acceleration. + \value InCirc \inlineimage qeasingcurve-incirc.png + \br + Easing equation function for a circular (sqrt(1-t^2)) easing + in: accelerating from zero velocity. + \value OutCirc \inlineimage qeasingcurve-outcirc.png + \br + Easing equation function for a circular (sqrt(1-t^2)) easing + out: decelerating from zero velocity. + \value InOutCirc \inlineimage qeasingcurve-inoutcirc.png + \br + Easing equation function for a circular (sqrt(1-t^2)) easing + in/out: acceleration until halfway, then deceleration. + \value OutInCirc \inlineimage qeasingcurve-outincirc.png + \br + Easing equation function for a circular (sqrt(1-t^2)) easing + out/in: deceleration until halfway, then acceleration. + \value InElastic \inlineimage qeasingcurve-inelastic.png + \br + Easing equation function for an elastic + (exponentially decaying sine wave) easing in: + accelerating from zero velocity. The peak amplitude + can be set with the \e amplitude parameter, and the + period of decay by the \e period parameter. + \value OutElastic \inlineimage qeasingcurve-outelastic.png + \br + Easing equation function for an elastic + (exponentially decaying sine wave) easing out: + decelerating from zero velocity. The peak amplitude + can be set with the \e amplitude parameter, and the + period of decay by the \e period parameter. + \value InOutElastic \inlineimage qeasingcurve-inoutelastic.png + \br + Easing equation function for an elastic + (exponentially decaying sine wave) easing in/out: + acceleration until halfway, then deceleration. + \value OutInElastic \inlineimage qeasingcurve-outinelastic.png + \br + Easing equation function for an elastic + (exponentially decaying sine wave) easing out/in: + deceleration until halfway, then acceleration. + \value InBack \inlineimage qeasingcurve-inback.png + \br + Easing equation function for a back (overshooting + cubic easing: (s+1)*t^3 - s*t^2) easing in: + accelerating from zero velocity. + \value OutBack \inlineimage qeasingcurve-outback.png + \br + Easing equation function for a back (overshooting + cubic easing: (s+1)*t^3 - s*t^2) easing out: + decelerating from zero velocity. + \value InOutBack \inlineimage qeasingcurve-inoutback.png + \br + Easing equation function for a back (overshooting + cubic easing: (s+1)*t^3 - s*t^2) easing in/out: + acceleration until halfway, then deceleration. + \value OutInBack \inlineimage qeasingcurve-outinback.png + \br + Easing equation function for a back (overshooting + cubic easing: (s+1)*t^3 - s*t^2) easing out/in: + deceleration until halfway, then acceleration. + \value InBounce \inlineimage qeasingcurve-inbounce.png + \br + Easing equation function for a bounce (exponentially + decaying parabolic bounce) easing in: accelerating + from zero velocity. + \value OutBounce \inlineimage qeasingcurve-outbounce.png + \br + Easing equation function for a bounce (exponentially + decaying parabolic bounce) easing out: decelerating + from zero velocity. + \value InOutBounce \inlineimage qeasingcurve-inoutbounce.png + \br + Easing equation function for a bounce (exponentially + decaying parabolic bounce) easing in/out: + acceleration until halfway, then deceleration. + \value OutInBounce \inlineimage qeasingcurve-outinbounce.png + \br + Easing equation function for a bounce (exponentially + decaying parabolic bounce) easing out/in: + deceleration until halfway, then acceleration. + \omitvalue InCurve + \omitvalue OutCurve + \omitvalue SineCurve + \omitvalue CosineCurve + \value Custom This is returned if the user have specified a custom curve type with setCustomType(). Note that you cannot call setType() with this value, but type() can return it. + \omitvalue NCurveTypes +*/ + +/*! + \typedef QEasingCurve::EasingFunction + + This is a typedef for a pointer to a function with the following + signature: + + \snippet doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp 0 +*/ + +#include "qeasingcurve.h" + +#ifndef QT_NO_DEBUG_STREAM +#include +#include +#endif + +QT_BEGIN_NAMESPACE + +static bool isConfigFunction(QEasingCurve::Type type) +{ + return type >= QEasingCurve::InElastic + && type <= QEasingCurve::OutInBounce; +} + +class QEasingCurveFunction +{ +public: + enum Type { In, Out, InOut, OutIn }; + + QEasingCurveFunction(QEasingCurveFunction::Type type = In, qreal period = 0.3, qreal amplitude = 1.0, + qreal overshoot = 1.70158f) + : _t(type), _p(period), _a(amplitude), _o(overshoot) + { } + virtual ~QEasingCurveFunction() {} + virtual qreal value(qreal t); + virtual QEasingCurveFunction *copy() const; + bool operator==(const QEasingCurveFunction& other); + + Type _t; + qreal _p; + qreal _a; + qreal _o; +}; + +qreal QEasingCurveFunction::value(qreal t) +{ + return t; +} + +QEasingCurveFunction *QEasingCurveFunction::copy() const +{ + return new QEasingCurveFunction(_t, _p, _a, _o); +} + +bool QEasingCurveFunction::operator==(const QEasingCurveFunction& other) +{ + return _t == other._t && + _p == other._p && + _a == other._a && + _o == other._o; +} + +QT_BEGIN_INCLUDE_NAMESPACE +#include "../../3rdparty/easing/easing.cpp" +QT_END_INCLUDE_NAMESPACE + +class QEasingCurvePrivate +{ +public: + QEasingCurvePrivate() + : type(QEasingCurve::Linear), + config(0), + func(&easeNone) + { } + ~QEasingCurvePrivate() { delete config; } + void setType_helper(QEasingCurve::Type); + + QEasingCurve::Type type; + QEasingCurveFunction *config; + QEasingCurve::EasingFunction func; +}; + +struct ElasticEase : public QEasingCurveFunction +{ + ElasticEase(Type type) + : QEasingCurveFunction(type, qreal(0.3), qreal(1.0)) + { } + + QEasingCurveFunction *copy() const + { + ElasticEase *rv = new ElasticEase(_t); + rv->_p = _p; + rv->_a = _a; + return rv; + } + + qreal value(qreal t) + { + qreal p = (_p < 0) ? 0.3f : _p; + qreal a = (_a < 0) ? 1.0f : _a; + switch(_t) { + case In: + return easeInElastic(t, a, p); + case Out: + return easeOutElastic(t, a, p); + case InOut: + return easeInOutElastic(t, a, p); + case OutIn: + return easeOutInElastic(t, a, p); + default: + return t; + } + } +}; + +struct BounceEase : public QEasingCurveFunction +{ + BounceEase(Type type) + : QEasingCurveFunction(type, 0.3f, 1.0f) + { } + + QEasingCurveFunction *copy() const + { + BounceEase *rv = new BounceEase(_t); + rv->_a = _a; + return rv; + } + + qreal value(qreal t) + { + qreal a = (_a < 0) ? 1.0f : _a; + switch(_t) { + case In: + return easeInBounce(t, a); + case Out: + return easeOutBounce(t, a); + case InOut: + return easeInOutBounce(t, a); + case OutIn: + return easeOutInBounce(t, a); + default: + return t; + } + } +}; + +struct BackEase : public QEasingCurveFunction +{ + BackEase(Type type) + : QEasingCurveFunction(type, 0.3f, 1.0f, 1.70158f) + { } + + QEasingCurveFunction *copy() const + { + BackEase *rv = new BackEase(_t); + rv->_o = _o; + return rv; + } + + qreal value(qreal t) + { + qreal o = (_o < 0) ? 1.70158f : _o; + switch(_t) { + case In: + return easeInBack(t, o); + case Out: + return easeOutBack(t, o); + case InOut: + return easeInOutBack(t, o); + case OutIn: + return easeOutInBack(t, o); + default: + return t; + } + } +}; + +static QEasingCurve::EasingFunction curveToFunc(QEasingCurve::Type curve) +{ + switch(curve) { + case QEasingCurve::Linear: + return &easeNone; + case QEasingCurve::InQuad: + return &easeInQuad; + case QEasingCurve::OutQuad: + return &easeOutQuad; + case QEasingCurve::InOutQuad: + return &easeInOutQuad; + case QEasingCurve::OutInQuad: + return &easeOutInQuad; + case QEasingCurve::InCubic: + return &easeInCubic; + case QEasingCurve::OutCubic: + return &easeOutCubic; + case QEasingCurve::InOutCubic: + return &easeInOutCubic; + case QEasingCurve::OutInCubic: + return &easeOutInCubic; + case QEasingCurve::InQuart: + return &easeInQuart; + case QEasingCurve::OutQuart: + return &easeOutQuart; + case QEasingCurve::InOutQuart: + return &easeInOutQuart; + case QEasingCurve::OutInQuart: + return &easeOutInQuart; + case QEasingCurve::InQuint: + return &easeInQuint; + case QEasingCurve::OutQuint: + return &easeOutQuint; + case QEasingCurve::InOutQuint: + return &easeInOutQuint; + case QEasingCurve::OutInQuint: + return &easeOutInQuint; + case QEasingCurve::InSine: + return &easeInSine; + case QEasingCurve::OutSine: + return &easeOutSine; + case QEasingCurve::InOutSine: + return &easeInOutSine; + case QEasingCurve::OutInSine: + return &easeOutInSine; + case QEasingCurve::InExpo: + return &easeInExpo; + case QEasingCurve::OutExpo: + return &easeOutExpo; + case QEasingCurve::InOutExpo: + return &easeInOutExpo; + case QEasingCurve::OutInExpo: + return &easeOutInExpo; + case QEasingCurve::InCirc: + return &easeInCirc; + case QEasingCurve::OutCirc: + return &easeOutCirc; + case QEasingCurve::InOutCirc: + return &easeInOutCirc; + case QEasingCurve::OutInCirc: + return &easeOutInCirc; + // Internal for, compatibility with QTimeLine only ?? + case QEasingCurve::InCurve: + return &easeInCurve; + case QEasingCurve::OutCurve: + return &easeOutCurve; + case QEasingCurve::SineCurve: + return &easeSineCurve; + case QEasingCurve::CosineCurve: + return &easeCosineCurve; + default: + return 0; + }; +} + +static QEasingCurveFunction *curveToFunctionObject(QEasingCurve::Type type) +{ + QEasingCurveFunction *curveFunc = 0; + switch(type) { + case QEasingCurve::InElastic: + curveFunc = new ElasticEase(ElasticEase::In); + break; + case QEasingCurve::OutElastic: + curveFunc = new ElasticEase(ElasticEase::Out); + break; + case QEasingCurve::InOutElastic: + curveFunc = new ElasticEase(ElasticEase::InOut); + break; + case QEasingCurve::OutInElastic: + curveFunc = new ElasticEase(ElasticEase::OutIn); + break; + case QEasingCurve::OutBounce: + curveFunc = new BounceEase(BounceEase::Out); + break; + case QEasingCurve::InBounce: + curveFunc = new BounceEase(BounceEase::In); + break; + case QEasingCurve::OutInBounce: + curveFunc = new BounceEase(BounceEase::OutIn); + break; + case QEasingCurve::InOutBounce: + curveFunc = new BounceEase(BounceEase::InOut); + break; + case QEasingCurve::InBack: + curveFunc = new BackEase(BackEase::In); + break; + case QEasingCurve::OutBack: + curveFunc = new BackEase(BackEase::Out); + break; + case QEasingCurve::InOutBack: + curveFunc = new BackEase(BackEase::InOut); + break; + case QEasingCurve::OutInBack: + curveFunc = new BackEase(BackEase::OutIn); + break; + default: + curveFunc = new QEasingCurveFunction(QEasingCurveFunction::In, 0.3f, 1.0f, 1.70158f); // ### + } + + return curveFunc; +} + +/*! + Constructs an easing curve of the given \a type. + */ +QEasingCurve::QEasingCurve(Type type) + : d_ptr(new QEasingCurvePrivate) +{ + setType(type); +} + +/*! + Construct a copy of \a other. + */ +QEasingCurve::QEasingCurve(const QEasingCurve &other) +: d_ptr(new QEasingCurvePrivate) +{ + // ### non-atomic, requires malloc on shallow copy + *d_ptr = *other.d_ptr; + if(other.d_ptr->config) + d_ptr->config = other.d_ptr->config->copy(); +} + +/*! + Destructor. + */ + +QEasingCurve::~QEasingCurve() +{ + delete d_ptr; +} + +/*! + Copy \a other. + */ +QEasingCurve &QEasingCurve::operator=(const QEasingCurve &other) +{ + // ### non-atomic, requires malloc on shallow copy + if (d_ptr->config) { + delete d_ptr->config; + d_ptr->config = 0; + } + + *d_ptr = *other.d_ptr; + if(other.d_ptr->config) + d_ptr->config = other.d_ptr->config->copy(); + + return *this; +} + +/*! + Compare this easing curve with \a other and returns true if they are + equal. It will also compare the properties of a curve. + */ +bool QEasingCurve::operator==(const QEasingCurve &other) const +{ + bool res = d_ptr->func == other.d_ptr->func + && d_ptr->type == other.d_ptr->type; + if (res && d_ptr->config && other.d_ptr->config) { + // catch the config content + res = d_ptr->config->operator==(*(other.d_ptr->config)); + } + return res; +} + +/*! + \fn bool QEasingCurve::operator!=(const QEasingCurve &other) const + Compare this easing curve with \a other and returns true if they are not equal. + It will also compare the properties of a curve. + + \sa operator==() +*/ + +/*! + Returns the amplitude. This is not applicable for all curve types. + It is only applicable for bounce and elastic curves (curves of type() + QEasingCurve::InBounce, QEasingCurve::OutBounce, QEasingCurve::InOutBounce, + QEasingCurve::OutInBounce, QEasingCurve::InElastic, QEasingCurve::OutElastic, + QEasingCurve::InOutElastic or QEasingCurve::OutInElastic). + */ +qreal QEasingCurve::amplitude() const +{ + return d_ptr->config ? d_ptr->config->_a : 1.0; +} + +/*! + Sets the amplitude to \a amplitude. + + This will set the amplitude of the bounce or the amplitude of the + elastic "spring" effect. The higher the number, the higher the amplitude. + \sa amplitude() +*/ +void QEasingCurve::setAmplitude(qreal amplitude) +{ + if (!d_ptr->config) + d_ptr->config = curveToFunctionObject(d_ptr->type); + d_ptr->config->_a = amplitude; +} + +/*! + Returns the period. This is not applicable for all curve types. + It is only applicable if type() is QEasingCurve::InElastic, QEasingCurve::OutElastic, + QEasingCurve::InOutElastic or QEasingCurve::OutInElastic. + */ +qreal QEasingCurve::period() const +{ + return d_ptr->config ? d_ptr->config->_p : 0.3; +} + +/*! + Sets the period to \a period. + Setting a small period value will give a high frequency of the curve. A + large period will give it a small frequency. + + \sa period() +*/ +void QEasingCurve::setPeriod(qreal period) +{ + if (!d_ptr->config) + d_ptr->config = curveToFunctionObject(d_ptr->type); + d_ptr->config->_p = period; +} + +/*! + Returns the overshoot. This is not applicable for all curve types. + It is only applicable if type() is QEasingCurve::InBack, QEasingCurve::OutBack, + QEasingCurve::InOutBack or QEasingCurve::OutInBack. + */ +qreal QEasingCurve::overshoot() const +{ + return d_ptr->config ? d_ptr->config->_o : 1.70158f; +} + +/*! + Sets the overshoot to \a overshoot. + + 0 produces no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent. + + \sa overshoot() +*/ +void QEasingCurve::setOvershoot(qreal overshoot) +{ + if (!d_ptr->config) + d_ptr->config = curveToFunctionObject(d_ptr->type); + d_ptr->config->_o = overshoot; +} + +/*! + Returns the type of the easing curve. +*/ +QEasingCurve::Type QEasingCurve::type() const +{ + return d_ptr->type; +} + +void QEasingCurvePrivate::setType_helper(QEasingCurve::Type newType) +{ + qreal amp = -1.0; + qreal period = -1.0; + qreal overshoot = -1.0; + + if (config) { + amp = config->_a; + period = config->_p; + overshoot = config->_o; + delete config; + config = 0; + } + + if (isConfigFunction(newType) || (amp != -1.0) || (period != -1.0) || (overshoot != -1.0)) { + config = curveToFunctionObject(newType); + if (amp != -1.0) + config->_a = amp; + if (period != -1.0) + config->_p = period; + if (overshoot != -1.0) + config->_o = overshoot; + func = 0; + } else if (newType != QEasingCurve::Custom) { + func = curveToFunc(newType); + } + Q_ASSERT((func == 0) == (config != 0)); + type = newType; +} + +/*! + Sets the type of the easing curve to \a type. +*/ +void QEasingCurve::setType(Type type) +{ + if (d_ptr->type == type) + return; + if (type < Linear || type >= NCurveTypes - 1) { + qWarning("QEasingCurve: Invalid curve type %d", type); + return; + } + + d_ptr->setType_helper(type); +} + +/*! + Sets a custom easing curve that is defined by the user in the function \a func. + The signature of the function is qreal myEasingFunction(qreal progress), + where \e progress and the return value is considered to be normalized between 0 and 1. + (In some cases the return value can be outside that range) + After calling this function type() will return QEasingCurve::Custom. + \a func cannot be zero. + + \sa customType() + \sa valueForProgress() +*/ +void QEasingCurve::setCustomType(EasingFunction func) +{ + if (!func) { + qWarning("Function pointer must not be null"); + return; + } + d_ptr->func = func; + d_ptr->setType_helper(Custom); +} + +/*! + Returns the function pointer to the custom easing curve. + If type() does not return QEasingCurve::Custom, this function + will return 0. +*/ +QEasingCurve::EasingFunction QEasingCurve::customType() const +{ + return d_ptr->type == Custom ? d_ptr->func : 0; +} + +/*! + Return the effective progress for the easing curve at \a progress. + While \a progress must be between 0 and 1, the returned effective progress + can be outside those bounds. For instance, QEasingCurve::InBack will + return negative values in the beginning of the function. + */ +qreal QEasingCurve::valueForProgress(qreal progress) const +{ + progress = qBound(0, progress, 1); + if (d_ptr->func) + return d_ptr->func(progress); + else if (d_ptr->config) + return d_ptr->config->value(progress); + else + return progress; +} + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QEasingCurve &item) +{ + debug << "type:" << item.d_ptr->type + << "func:" << item.d_ptr->func; + if (item.d_ptr->config) { + debug << QString::fromAscii("period:%1").arg(item.d_ptr->config->_p, 0, 'f', 20) + << QString::fromAscii("amp:%1").arg(item.d_ptr->config->_a, 0, 'f', 20) + << QString::fromAscii("overshoot:%1").arg(item.d_ptr->config->_o, 0, 'f', 20); + } + return debug; +} +#endif + +QT_END_NAMESPACE diff --git a/src/corelib/tools/qeasingcurve.h b/src/corelib/tools/qeasingcurve.h new file mode 100644 index 0000000..a240bc0 --- /dev/null +++ b/src/corelib/tools/qeasingcurve.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEASINGCURVE_H +#define QEASINGCURVE_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QEasingCurvePrivate; +class Q_CORE_EXPORT QEasingCurve +{ + Q_GADGET + Q_ENUMS(Type) +public: + enum Type { + Linear, + InQuad, OutQuad, InOutQuad, OutInQuad, + InCubic, OutCubic, InOutCubic, OutInCubic, + InQuart, OutQuart, InOutQuart, OutInQuart, + InQuint, OutQuint, InOutQuint, OutInQuint, + InSine, OutSine, InOutSine, OutInSine, + InExpo, OutExpo, InOutExpo, OutInExpo, + InCirc, OutCirc, InOutCirc, OutInCirc, + InElastic, OutElastic, InOutElastic, OutInElastic, + InBack, OutBack, InOutBack, OutInBack, + InBounce, OutBounce, InOutBounce, OutInBounce, + InCurve, OutCurve, SineCurve, CosineCurve, + Custom, NCurveTypes + }; + + QEasingCurve(Type type = Linear); + QEasingCurve(const QEasingCurve &other); + ~QEasingCurve(); + + QEasingCurve &operator=(const QEasingCurve &other); + bool operator==(const QEasingCurve &other) const; + inline bool operator!=(const QEasingCurve &other) const + { return !(this->operator==(other)); } + + qreal amplitude() const; + void setAmplitude(qreal amplitude); + + qreal period() const; + void setPeriod(qreal period); + + qreal overshoot() const; + void setOvershoot(qreal overshoot); + + Type type() const; + void setType(Type type); + typedef qreal (*EasingFunction)(qreal progress); + void setCustomType(EasingFunction func); + EasingFunction customType() const; + + qreal valueForProgress(qreal progress) const; +private: + QEasingCurvePrivate *d_ptr; + friend Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QEasingCurve &item); +}; + +#ifndef QT_NO_DEBUG_STREAM +Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QEasingCurve &item); +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index 3a03558..ee4f73c 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -48,20 +48,6 @@ QT_BEGIN_NAMESPACE -static const qreal pi = qreal(3.14159265359); -static const qreal halfPi = pi / qreal(2.0); - - -static inline qreal qt_sinProgress(qreal value) -{ - return qSin((value * pi) - halfPi) / 2 + qreal(0.5); -} - -static inline qreal qt_smoothBeginEndMixFactor(qreal value) -{ - return qMin(qMax(1 - value * 2 + qreal(0.3), qreal(0.0)), qreal(1.0)); -} - class QTimeLinePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QTimeLine) @@ -70,7 +56,7 @@ public: : startTime(0), duration(1000), startFrame(0), endFrame(0), updateInterval(1000 / 25), totalLoopCount(1), currentLoopCount(0), currentTime(0), timerId(0), - direction(QTimeLine::Forward), curveShape(QTimeLine::EaseInOutCurve), + direction(QTimeLine::Forward), easingCurve(QEasingCurve::InOutSine), state(QTimeLine::NotRunning) { } @@ -88,7 +74,7 @@ public: QTime timer; QTimeLine::Direction direction; - QTimeLine::CurveShape curveShape; + QEasingCurve easingCurve; QTimeLine::State state; inline void setState(QTimeLine::State newState) { @@ -523,12 +509,68 @@ void QTimeLine::setUpdateInterval(int interval) QTimeLine::CurveShape QTimeLine::curveShape() const { Q_D(const QTimeLine); - return d->curveShape; + switch (d->easingCurve.type()) { + default: + case QEasingCurve::InOutSine: + return EaseInOutCurve; + case QEasingCurve::InCurve: + return EaseInCurve; + case QEasingCurve::OutCurve: + return EaseOutCurve; + case QEasingCurve::Linear: + return LinearCurve; + case QEasingCurve::SineCurve: + return SineCurve; + case QEasingCurve::CosineCurve: + return CosineCurve; + } + return EaseInOutCurve; } + void QTimeLine::setCurveShape(CurveShape shape) { + switch (shape) { + default: + case EaseInOutCurve: + setEasingCurve(QEasingCurve(QEasingCurve::InOutSine)); + break; + case EaseInCurve: + setEasingCurve(QEasingCurve(QEasingCurve::InCurve)); + break; + case EaseOutCurve: + setEasingCurve(QEasingCurve(QEasingCurve::OutCurve)); + break; + case LinearCurve: + setEasingCurve(QEasingCurve(QEasingCurve::Linear)); + break; + case SineCurve: + setEasingCurve(QEasingCurve(QEasingCurve::SineCurve)); + break; + case CosineCurve: + setEasingCurve(QEasingCurve(QEasingCurve::CosineCurve)); + break; + } +} + +/*! + \property QTimeLine::easingCurve + + Specifies the easing curve that the timeline will use. + If both easing curve and curveShape are set, the last set property will + override the previous one. (If valueForTime() is reimplemented it will + override both) +*/ + +QEasingCurve QTimeLine::easingCurve() const +{ + Q_D(const QTimeLine); + return d->easingCurve; +} + +void QTimeLine::setEasingCurve(const QEasingCurve& curve) +{ Q_D(QTimeLine); - d->curveShape = shape; + d->easingCurve = curve; } /*! @@ -608,42 +650,8 @@ qreal QTimeLine::valueForTime(int msec) const Q_D(const QTimeLine); msec = qMin(qMax(msec, 0), d->duration); - // Simple linear interpolation qreal value = msec / qreal(d->duration); - - switch (d->curveShape) { - case EaseInOutCurve: - value = qt_sinProgress(value); - break; - // SmoothBegin blends Smooth and Linear Interpolation. - // Progress 0 - 0.3 : Smooth only - // Progress 0.3 - ~ 0.5 : Mix of Smooth and Linear - // Progress ~ 0.5 - 1 : Linear only - case EaseInCurve: { - const qreal sinProgress = qt_sinProgress(value); - const qreal linearProgress = value; - const qreal mix = qt_smoothBeginEndMixFactor(value); - value = sinProgress * mix + linearProgress * (1 - mix); - break; - } - case EaseOutCurve: { - const qreal sinProgress = qt_sinProgress(value); - const qreal linearProgress = value; - const qreal mix = qt_smoothBeginEndMixFactor(1 - value); - value = sinProgress * mix + linearProgress * (1 - mix); - break; - } - case SineCurve: - value = (qSin(((msec * pi * 2) / d->duration) - pi/2) + 1) / 2; - break; - case CosineCurve: - value = (qCos(((msec * pi * 2) / d->duration) - pi/2) + 1) / 2; - break; - default: - break; - } - - return value; + return d->easingCurve.valueForProgress(value); } /*! diff --git a/src/corelib/tools/qtimeline.h b/src/corelib/tools/qtimeline.h index 18c3980..48c9232 100644 --- a/src/corelib/tools/qtimeline.h +++ b/src/corelib/tools/qtimeline.h @@ -42,6 +42,7 @@ #ifndef QTIMELINE_H #define QTIMELINE_H +#include #include QT_BEGIN_HEADER @@ -60,6 +61,7 @@ class Q_CORE_EXPORT QTimeLine : public QObject Q_PROPERTY(Direction direction READ direction WRITE setDirection) Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount) Q_PROPERTY(CurveShape curveShape READ curveShape WRITE setCurveShape) + Q_PROPERTY(QEasingCurve easingCurve READ easingCurve WRITE setEasingCurve) public: enum State { NotRunning, @@ -105,6 +107,9 @@ public: CurveShape curveShape() const; void setCurveShape(CurveShape shape); + QEasingCurve easingCurve() const; + void setEasingCurve(const QEasingCurve &curve); + int currentTime() const; int currentFrame() const; qreal currentValue() const; diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index a6fdac7..90287cb 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -11,6 +11,7 @@ HEADERS += \ tools/qcryptographichash.h \ tools/qdatetime.h \ tools/qdatetime_p.h \ + tools/qeasingcurve.h \ tools/qhash.h \ tools/qline.h \ tools/qlinkedlist.h \ @@ -46,6 +47,7 @@ SOURCES += \ tools/qbytearraymatcher.cpp \ tools/qcryptographichash.cpp \ tools/qdatetime.cpp \ + tools/qeasingcurve.cpp \ tools/qhash.cpp \ tools/qline.cpp \ tools/qlinkedlist.cpp \ diff --git a/src/gui/animation/animation.pri b/src/gui/animation/animation.pri new file mode 100644 index 0000000..27763ca --- /dev/null +++ b/src/gui/animation/animation.pri @@ -0,0 +1,3 @@ +# Qt gui animation module + +SOURCES += animation/qguivariantanimation.cpp diff --git a/src/gui/animation/qguivariantanimation.cpp b/src/gui/animation/qguivariantanimation.cpp new file mode 100644 index 0000000..37ca6a1 --- /dev/null +++ b/src/gui/animation/qguivariantanimation.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_NO_ANIMATION + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +template<> Q_INLINE_TEMPLATE QColor _q_interpolate(const QColor &f,const QColor &t, qreal progress) +{ + return QColor(_q_interpolate(f.red(), t.red(), progress), + _q_interpolate(f.green(), t.green(), progress), + _q_interpolate(f.blue(), t.blue(), progress), + _q_interpolate(f.alpha(), t.alpha(), progress)); +} + +static int qRegisterGuiGetInterpolator() +{ + qRegisterAnimationInterpolator(_q_interpolateVariant); + return 1; +} +Q_CONSTRUCTOR_FUNCTION(qRegisterGuiGetInterpolator) + +static int qUnregisterGuiGetInterpolator() +{ + qRegisterAnimationInterpolator(0); + return 1; +} +Q_DESTRUCTOR_FUNCTION(qUnregisterGuiGetInterpolator) + +QT_END_NAMESPACE + +#endif //QT_NO_ANIMATION diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index b2569c1..62e0411 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -95,6 +95,15 @@ class Q_AUTOTEST_EXPORT QGraphicsItemPrivate { Q_DECLARE_PUBLIC(QGraphicsItem) public: + struct TransformData + { + TransformData() : rotationX(0),rotationY(0),rotationZ(0),scaleX(1),scaleY(1), dirty(true) {} + QTransform baseTransform; + QTransform transform; + QPointF transformCenter; + qreal rotationX,rotationY,rotationZ,scaleX,scaleY; + bool dirty; + }; enum Extra { ExtraTransform, ExtraToolTip, @@ -239,7 +248,7 @@ public: } } } - + struct ExtraStruct { ExtraStruct(Extra type, QVariant value) : type(type), value(value) @@ -251,6 +260,7 @@ public: bool operator<(Extra extra) const { return type < extra; } }; + QList extras; QGraphicsItemCache *maybeExtraItemCache() const; diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 01b7593..a5b11ff 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -976,6 +976,7 @@ void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *even } #endif // QT_NO_CONTEXTMENU +#ifndef QT_NO_DRAGANDDROP /*! \reimp */ @@ -1096,6 +1097,7 @@ void QGraphicsProxyWidget::dropEvent(QGraphicsSceneDragDropEvent *event) } #endif } +#endif /*! \reimp diff --git a/src/gui/graphicsview/qgraphicsproxywidget.h b/src/gui/graphicsview/qgraphicsproxywidget.h index b2c3c8f..ab8c9da 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.h +++ b/src/gui/graphicsview/qgraphicsproxywidget.h @@ -90,10 +90,12 @@ protected: void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); #endif +#ifndef QT_NO_DRAGANDDROP void dragEnterEvent(QGraphicsSceneDragDropEvent *event); void dragLeaveEvent(QGraphicsSceneDragDropEvent *event); void dragMoveEvent(QGraphicsSceneDragDropEvent *event); void dropEvent(QGraphicsSceneDragDropEvent *event); +#endif void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 1aa6558..329fb01 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -19,6 +19,7 @@ win32:include(kernel/win.pri) embedded:include(embedded/embedded.pri) #modules +include(animation/animation.pri) include(kernel/kernel.pri) include(image/image.pri) include(painting/painting.pri) @@ -31,6 +32,7 @@ include(itemviews/itemviews.pri) include(inputmethod/inputmethod.pri) include(graphicsview/graphicsview.pri) include(util/util.pri) +include(statemachine/statemachine.pri) include(math3d/math3d.pri) embedded: QT += network diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 824d6f1..a9424db 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -838,6 +838,9 @@ void QApplicationPrivate::initialize() // trigger registering of QVariant's GUI types extern int qRegisterGuiVariant(); qRegisterGuiVariant(); + // trigger registering of QStateMachine's GUI types + extern int qRegisterGuiStateMachine(); + qRegisterGuiStateMachine(); is_app_running = true; // no longer starting up @@ -1059,6 +1062,9 @@ QApplication::~QApplication() QApplicationPrivate::fade_tooltip = false; QApplicationPrivate::widgetCount = false; + // trigger unregistering of QStateMachine's GUI types + extern int qUnregisterGuiStateMachine(); + qUnregisterGuiStateMachine(); // trigger unregistering of QVariant's GUI types extern int qUnregisterGuiVariant(); qUnregisterGuiVariant(); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index fdd0c21..bbe1a76 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6930,7 +6930,7 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, } void qt_build_pow_tables() { - qreal smoothing = 1.7; + qreal smoothing = qreal(1.7); #ifdef Q_WS_MAC // decided by testing a few things on an iMac, should probably get this from the @@ -6952,15 +6952,15 @@ void qt_build_pow_tables() { } #else for (int i=0; i<256; ++i) { - qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / 255.0, smoothing) * 255)); - qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / 255.0, 1 / smoothing) * 255)); + qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / qreal(255.0), smoothing) * 255)); + qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / qreal(255.), 1 / smoothing) * 255)); } #endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) const qreal gray_gamma = 2.31; for (int i=0; i<256; ++i) - qt_pow_gamma[i] = uint(qRound(pow(i / 255.0, gray_gamma) * 2047)); + qt_pow_gamma[i] = uint(qRound(pow(i / qreal(255.), gray_gamma) * 2047)); for (int i=0; i<2048; ++i) qt_pow_invgamma[i] = uchar(qRound(pow(i / 2047.0, 1 / gray_gamma) * 255)); #endif diff --git a/src/gui/statemachine/qbasickeyeventtransition.cpp b/src/gui/statemachine/qbasickeyeventtransition.cpp new file mode 100644 index 0000000..f7f1eb6 --- /dev/null +++ b/src/gui/statemachine/qbasickeyeventtransition.cpp @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbasickeyeventtransition_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \internal + \class QBasicKeyEventTransition + \since 4.6 + \ingroup statemachine + + \brief The QBasicKeyEventTransition class provides a transition for Qt key events. +*/ + +class QBasicKeyEventTransitionPrivate : public QAbstractTransitionPrivate +{ + Q_DECLARE_PUBLIC(QBasicKeyEventTransition) +public: + QBasicKeyEventTransitionPrivate(); + + static QBasicKeyEventTransitionPrivate *get(QBasicKeyEventTransition *q); + + QEvent::Type eventType; + int key; + Qt::KeyboardModifiers modifiersMask; +}; + +QBasicKeyEventTransitionPrivate::QBasicKeyEventTransitionPrivate() +{ + eventType = QEvent::None; + key = 0; + modifiersMask = Qt::NoModifier; +} + +QBasicKeyEventTransitionPrivate *QBasicKeyEventTransitionPrivate::get(QBasicKeyEventTransition *q) +{ + return q->d_func(); +} + +/*! + Constructs a new key event transition with the given \a sourceState. +*/ +QBasicKeyEventTransition::QBasicKeyEventTransition(QState *sourceState) + : QAbstractTransition(*new QBasicKeyEventTransitionPrivate, sourceState) +{ +} + +/*! + Constructs a new event transition for events of the given \a type for the + given \a key, with the given \a sourceState. +*/ +QBasicKeyEventTransition::QBasicKeyEventTransition(QEvent::Type type, int key, + QState *sourceState) + : QAbstractTransition(*new QBasicKeyEventTransitionPrivate, sourceState) +{ + Q_D(QBasicKeyEventTransition); + d->eventType = type; + d->key = key; +} + +/*! + Constructs a new event transition for events of the given \a type for the + given \a key, with the given \a modifiersMask and \a sourceState. +*/ +QBasicKeyEventTransition::QBasicKeyEventTransition(QEvent::Type type, int key, + Qt::KeyboardModifiers modifiersMask, + QState *sourceState) + : QAbstractTransition(*new QBasicKeyEventTransitionPrivate, sourceState) +{ + Q_D(QBasicKeyEventTransition); + d->eventType = type; + d->key = key; + d->modifiersMask = modifiersMask; +} + +/*! + Destroys this event transition. +*/ +QBasicKeyEventTransition::~QBasicKeyEventTransition() +{ +} + +/*! + Returns the event type that this key event transition is associated with. +*/ +QEvent::Type QBasicKeyEventTransition::eventType() const +{ + Q_D(const QBasicKeyEventTransition); + return d->eventType; +} + +/*! + Sets the event \a type that this key event transition is associated with. +*/ +void QBasicKeyEventTransition::setEventType(QEvent::Type type) +{ + Q_D(QBasicKeyEventTransition); + d->eventType = type; +} + +/*! + Returns the key that this key event transition checks for. +*/ +int QBasicKeyEventTransition::key() const +{ + Q_D(const QBasicKeyEventTransition); + return d->key; +} + +/*! + Sets the key that this key event transition will check for. +*/ +void QBasicKeyEventTransition::setKey(int key) +{ + Q_D(QBasicKeyEventTransition); + d->key = key; +} + +/*! + Returns the keyboard modifiers mask that this key event transition checks + for. +*/ +Qt::KeyboardModifiers QBasicKeyEventTransition::modifiersMask() const +{ + Q_D(const QBasicKeyEventTransition); + return d->modifiersMask; +} + +/*! + Sets the keyboard modifiers mask that this key event transition will check + for. +*/ +void QBasicKeyEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask) +{ + Q_D(QBasicKeyEventTransition); + d->modifiersMask = modifiersMask; +} + +/*! + \reimp +*/ +bool QBasicKeyEventTransition::eventTest(QEvent *event) +{ + Q_D(const QBasicKeyEventTransition); + if (event->type() == d->eventType) { + QKeyEvent *ke = static_cast(event); + return (ke->key() == d->key) + && ((ke->modifiers() & d->modifiersMask) == d->modifiersMask); + } + return false; +} + +/*! + \reimp +*/ +void QBasicKeyEventTransition::onTransition(QEvent *) +{ +} + +QT_END_NAMESPACE diff --git a/src/gui/statemachine/qbasickeyeventtransition_p.h b/src/gui/statemachine/qbasickeyeventtransition_p.h new file mode 100644 index 0000000..39fa6ad --- /dev/null +++ b/src/gui/statemachine/qbasickeyeventtransition_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBASICKEYEVENTTRANSITION_P_H +#define QBASICKEYEVENTTRANSITION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +class QBasicKeyEventTransitionPrivate; +class Q_AUTOTEST_EXPORT QBasicKeyEventTransition : public QAbstractTransition +{ + Q_OBJECT +public: + QBasicKeyEventTransition(QState *sourceState = 0); + QBasicKeyEventTransition(QEvent::Type type, int key, QState *sourceState = 0); + QBasicKeyEventTransition(QEvent::Type type, int key, + Qt::KeyboardModifiers modifiersMask, + QState *sourceState = 0); + ~QBasicKeyEventTransition(); + + QEvent::Type eventType() const; + void setEventType(QEvent::Type type); + + int key() const; + void setKey(int key); + + Qt::KeyboardModifiers modifiersMask() const; + void setModifiersMask(Qt::KeyboardModifiers modifiers); + +protected: + bool eventTest(QEvent *event); + void onTransition(QEvent *); + +private: + Q_DISABLE_COPY(QBasicKeyEventTransition) + Q_DECLARE_PRIVATE(QBasicKeyEventTransition) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/statemachine/qbasicmouseeventtransition.cpp b/src/gui/statemachine/qbasicmouseeventtransition.cpp new file mode 100644 index 0000000..20dd792 --- /dev/null +++ b/src/gui/statemachine/qbasicmouseeventtransition.cpp @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbasicmouseeventtransition_p.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \internal + \class QBasicMouseEventTransition + \since 4.6 + \ingroup statemachine + + \brief The QBasicMouseEventTransition class provides a transition for Qt mouse events. +*/ + +class QBasicMouseEventTransitionPrivate : public QAbstractTransitionPrivate +{ + Q_DECLARE_PUBLIC(QBasicMouseEventTransition) +public: + QBasicMouseEventTransitionPrivate(); + + static QBasicMouseEventTransitionPrivate *get(QBasicMouseEventTransition *q); + + QEvent::Type eventType; + Qt::MouseButton button; + Qt::KeyboardModifiers modifiersMask; + QPainterPath path; +}; + +QBasicMouseEventTransitionPrivate::QBasicMouseEventTransitionPrivate() +{ + eventType = QEvent::None; + button = Qt::NoButton; +} + +QBasicMouseEventTransitionPrivate *QBasicMouseEventTransitionPrivate::get(QBasicMouseEventTransition *q) +{ + return q->d_func(); +} + +/*! + Constructs a new mouse event transition with the given \a sourceState. +*/ +QBasicMouseEventTransition::QBasicMouseEventTransition(QState *sourceState) + : QAbstractTransition(*new QBasicMouseEventTransitionPrivate, sourceState) +{ +} + +/*! + Constructs a new mouse event transition for events of the given \a type. +*/ +QBasicMouseEventTransition::QBasicMouseEventTransition(QEvent::Type type, + Qt::MouseButton button, + QState *sourceState) + : QAbstractTransition(*new QBasicMouseEventTransitionPrivate, sourceState) +{ + Q_D(QBasicMouseEventTransition); + d->eventType = type; + d->button = button; +} + +/*! + Destroys this mouse event transition. +*/ +QBasicMouseEventTransition::~QBasicMouseEventTransition() +{ +} + +/*! + Returns the event type that this mouse event transition is associated with. +*/ +QEvent::Type QBasicMouseEventTransition::eventType() const +{ + Q_D(const QBasicMouseEventTransition); + return d->eventType; +} + +/*! + Sets the event \a type that this mouse event transition is associated with. +*/ +void QBasicMouseEventTransition::setEventType(QEvent::Type type) +{ + Q_D(QBasicMouseEventTransition); + d->eventType = type; +} + +/*! + Returns the button that this mouse event transition checks for. +*/ +Qt::MouseButton QBasicMouseEventTransition::button() const +{ + Q_D(const QBasicMouseEventTransition); + return d->button; +} + +/*! + Sets the button that this mouse event transition will check for. +*/ +void QBasicMouseEventTransition::setButton(Qt::MouseButton button) +{ + Q_D(QBasicMouseEventTransition); + d->button = button; +} + +/*! + Returns the keyboard modifiers mask that this mouse event transition checks + for. +*/ +Qt::KeyboardModifiers QBasicMouseEventTransition::modifiersMask() const +{ + Q_D(const QBasicMouseEventTransition); + return d->modifiersMask; +} + +/*! + Sets the keyboard modifiers mask that this mouse event transition will check + for. +*/ +void QBasicMouseEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask) +{ + Q_D(QBasicMouseEventTransition); + d->modifiersMask = modifiersMask; +} + +/*! + Returns the path for this mouse event transition. +*/ +QPainterPath QBasicMouseEventTransition::path() const +{ + Q_D(const QBasicMouseEventTransition); + return d->path; +} + +/*! + Sets the path for this mouse event transition. +*/ +void QBasicMouseEventTransition::setPath(const QPainterPath &path) +{ + Q_D(QBasicMouseEventTransition); + d->path = path; +} + +/*! + \reimp +*/ +bool QBasicMouseEventTransition::eventTest(QEvent *event) +{ + Q_D(const QBasicMouseEventTransition); + if (event->type() == d->eventType) { + QMouseEvent *me = static_cast(event); + return (me->button() == d->button) + && ((me->modifiers() & d->modifiersMask) == d->modifiersMask) + && (d->path.isEmpty() || d->path.contains(me->pos())); + } + return false; +} + +/*! + \reimp +*/ +void QBasicMouseEventTransition::onTransition(QEvent *) +{ +} + +QT_END_NAMESPACE diff --git a/src/gui/statemachine/qbasicmouseeventtransition_p.h b/src/gui/statemachine/qbasicmouseeventtransition_p.h new file mode 100644 index 0000000..6c0afe4 --- /dev/null +++ b/src/gui/statemachine/qbasicmouseeventtransition_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBASICMOUSEEVENTTRANSITION_P_H +#define QBASICMOUSEEVENTTRANSITION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +class QPainterPath; + +class QBasicMouseEventTransitionPrivate; +class Q_AUTOTEST_EXPORT QBasicMouseEventTransition : public QAbstractTransition +{ + Q_OBJECT +public: + QBasicMouseEventTransition(QState *sourceState = 0); + QBasicMouseEventTransition(QEvent::Type type, Qt::MouseButton button, + QState *sourceState = 0); + ~QBasicMouseEventTransition(); + + QEvent::Type eventType() const; + void setEventType(QEvent::Type type); + + Qt::MouseButton button() const; + void setButton(Qt::MouseButton button); + + Qt::KeyboardModifiers modifiersMask() const; + void setModifiersMask(Qt::KeyboardModifiers modifiers); + + QPainterPath path() const; + void setPath(const QPainterPath &path); + +protected: + bool eventTest(QEvent *event); + void onTransition(QEvent *); + +private: + Q_DISABLE_COPY(QBasicMouseEventTransition) + Q_DECLARE_PRIVATE(QBasicMouseEventTransition) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp new file mode 100644 index 0000000..612e43e --- /dev/null +++ b/src/gui/statemachine/qguistatemachine.cpp @@ -0,0 +1,559 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +Q_CORE_EXPORT const QStateMachinePrivate::Handler *qcoreStateMachineHandler(); + +static QEvent *cloneEvent(QEvent *e) +{ + switch (e->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + return new QMouseEvent(*static_cast(e)); + case QEvent::KeyPress: + case QEvent::KeyRelease: + return new QKeyEvent(*static_cast(e)); + case QEvent::FocusIn: + case QEvent::FocusOut: + return new QFocusEvent(*static_cast(e)); + case QEvent::Enter: + return new QEvent(*e); + case QEvent::Leave: + return new QEvent(*e); + break; + case QEvent::Paint: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::Move: + return new QMoveEvent(*static_cast(e)); + case QEvent::Resize: + return new QResizeEvent(*static_cast(e)); + case QEvent::Create: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::Destroy: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::Show: + return new QShowEvent(*static_cast(e)); + case QEvent::Hide: + return new QHideEvent(*static_cast(e)); + case QEvent::Close: + return new QCloseEvent(*static_cast(e)); + case QEvent::Quit: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ParentChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ParentAboutToChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ThreadChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::WindowActivate: + case QEvent::WindowDeactivate: + return new QEvent(*e); + + case QEvent::ShowToParent: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::HideToParent: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::Wheel: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::WindowTitleChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::WindowIconChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ApplicationWindowIconChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ApplicationFontChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ApplicationLayoutDirectionChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ApplicationPaletteChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::PaletteChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::Clipboard: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::Speech: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::MetaCall: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::SockAct: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::WinEventAct: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::DeferredDelete: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::DragEnter: + return new QDragEnterEvent(*static_cast(e)); + case QEvent::DragMove: + return new QDragMoveEvent(*static_cast(e)); + case QEvent::DragLeave: + return new QDragLeaveEvent(*static_cast(e)); + case QEvent::Drop: + return new QDropEvent(*static_cast(e)); + case QEvent::DragResponse: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ChildAdded: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ChildPolished: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; +#ifdef QT3_SUPPORT + case QEvent::ChildInsertedRequest: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ChildInserted: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::LayoutHint: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; +#endif + case QEvent::ChildRemoved: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ShowWindowRequest: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::PolishRequest: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::Polish: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::LayoutRequest: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::UpdateRequest: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::UpdateLater: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::EmbeddingControl: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ActivateControl: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::DeactivateControl: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ContextMenu: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::InputMethod: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::AccessibilityPrepare: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::TabletMove: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::LocaleChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::LanguageChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::LayoutDirectionChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::Style: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::TabletPress: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::TabletRelease: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::OkRequest: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::HelpRequest: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::IconDrag: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::FontChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::EnabledChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ActivationChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::StyleChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::IconTextChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ModifiedChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::MouseTrackingChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::WindowBlocked: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::WindowUnblocked: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::WindowStateChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::ToolTip: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::WhatsThis: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::StatusTip: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::ActionChanged: + case QEvent::ActionAdded: + case QEvent::ActionRemoved: + return new QActionEvent(*static_cast(e)); + + case QEvent::FileOpen: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::Shortcut: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ShortcutOverride: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + +#ifdef QT3_SUPPORT + case QEvent::Accel: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::AccelAvailable: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; +#endif + + case QEvent::WhatsThisClicked: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::ToolBarChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::ApplicationActivate: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ApplicationDeactivate: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::QueryWhatsThis: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::EnterWhatsThisMode: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::LeaveWhatsThisMode: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::ZOrderChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::HoverEnter: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::HoverLeave: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::HoverMove: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::AccessibilityHelp: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::AccessibilityDescription: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + +#ifdef QT_KEYPAD_NAVIGATION + case QEvent::EnterEditFocus: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::LeaveEditFocus: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; +#endif + case QEvent::AcceptDropsChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::MenubarUpdated: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::ZeroTimerEvent: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::GraphicsSceneMouseMove: + case QEvent::GraphicsSceneMousePress: + case QEvent::GraphicsSceneMouseRelease: + case QEvent::GraphicsSceneMouseDoubleClick: { + QGraphicsSceneMouseEvent *me = static_cast(e); + QGraphicsSceneMouseEvent *me2 = new QGraphicsSceneMouseEvent(me->type()); + me2->setWidget(me->widget()); + me2->setPos(me->pos()); + me2->setScenePos(me->scenePos()); + me2->setScreenPos(me->screenPos()); +// ### for all buttons + me2->setButtonDownPos(Qt::LeftButton, me->buttonDownPos(Qt::LeftButton)); + me2->setButtonDownPos(Qt::RightButton, me->buttonDownPos(Qt::RightButton)); + me2->setButtonDownScreenPos(Qt::LeftButton, me->buttonDownScreenPos(Qt::LeftButton)); + me2->setButtonDownScreenPos(Qt::RightButton, me->buttonDownScreenPos(Qt::RightButton)); + me2->setLastPos(me->lastPos()); + me2->setLastScenePos(me->lastScenePos()); + me2->setLastScreenPos(me->lastScreenPos()); + me2->setButtons(me->buttons()); + me2->setButton(me->button()); + me2->setModifiers(me->modifiers()); + return me2; + } + + case QEvent::GraphicsSceneContextMenu: { + QGraphicsSceneContextMenuEvent *me = static_cast(e); + QGraphicsSceneContextMenuEvent *me2 = new QGraphicsSceneContextMenuEvent(me->type()); + me2->setWidget(me->widget()); + me2->setPos(me->pos()); + me2->setScenePos(me->scenePos()); + me2->setScreenPos(me->screenPos()); + me2->setModifiers(me->modifiers()); + me2->setReason(me->reason()); + return me2; + } + + case QEvent::GraphicsSceneHoverEnter: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::GraphicsSceneHoverMove: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::GraphicsSceneHoverLeave: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::GraphicsSceneHelp: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::GraphicsSceneDragEnter: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::GraphicsSceneDragMove: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::GraphicsSceneDragLeave: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::GraphicsSceneDrop: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::GraphicsSceneWheel: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::KeyboardLayoutChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::DynamicPropertyChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::TabletEnterProximity: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::TabletLeaveProximity: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::NonClientAreaMouseMove: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::NonClientAreaMouseButtonPress: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::NonClientAreaMouseButtonRelease: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::NonClientAreaMouseButtonDblClick: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::MacSizeChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::ContentsRectChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::MacGLWindowChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::FutureCallOut: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::GraphicsSceneResize: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::GraphicsSceneMove: { + QGraphicsSceneMoveEvent *me = static_cast(e); + QGraphicsSceneMoveEvent *me2 = new QGraphicsSceneMoveEvent(); + me2->setWidget(me->widget()); + me2->setNewPos(me->newPos()); + me2->setOldPos(me->oldPos()); + return me2; + } + + case QEvent::CursorChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + case QEvent::ToolTipChange: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::NetworkReplyUpdated: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + + case QEvent::GrabMouse: + case QEvent::UngrabMouse: + case QEvent::GrabKeyboard: + case QEvent::UngrabKeyboard: + return new QEvent(*e); + +#ifdef QT_MAC_USE_COCOA + case QEvent::CocoaRequestModal: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; +#endif + case QEvent::User: + case QEvent::MaxUser: + Q_ASSERT_X(false, "cloneEvent()", "not implemented"); + break; + default: + ; + } + return qcoreStateMachineHandler()->cloneEvent(e); +} + +const QStateMachinePrivate::Handler qt_gui_statemachine_handler = { + cloneEvent +}; + +static const QStateMachinePrivate::Handler *qt_guistatemachine_last_handler = 0; +int qRegisterGuiStateMachine() +{ + qt_guistatemachine_last_handler = QStateMachinePrivate::handler; + QStateMachinePrivate::handler = &qt_gui_statemachine_handler; + return 1; +} +Q_CONSTRUCTOR_FUNCTION(qRegisterGuiStateMachine) + +int qUnregisterGuiStateMachine() +{ + QStateMachinePrivate::handler = qt_guistatemachine_last_handler; + return 1; +} +Q_DESTRUCTOR_FUNCTION(qUnregisterGuiStateMachine) + +QT_END_NAMESPACE diff --git a/src/gui/statemachine/qkeyeventtransition.cpp b/src/gui/statemachine/qkeyeventtransition.cpp new file mode 100644 index 0000000..f803711 --- /dev/null +++ b/src/gui/statemachine/qkeyeventtransition.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qkeyeventtransition.h" +#include "qbasickeyeventtransition_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QKeyEventTransition + + \brief The QKeyEventTransition class provides a transition for key events. + + \since 4.6 + \ingroup statemachine + + QKeyEventTransition is part of \l{The State Machine Framework}. + + \sa QState::addTransition() +*/ + +/*! + \property QKeyEventTransition::key + + \brief the key that this key event transition is associated with +*/ + +/*! + \property QKeyEventTransition::modifiersMask + + \brief the keyboard modifiers mask that this key event transition checks for +*/ + +class QKeyEventTransitionPrivate : public QEventTransitionPrivate +{ + Q_DECLARE_PUBLIC(QKeyEventTransition) +public: + QKeyEventTransitionPrivate() {} + + QBasicKeyEventTransition *transition; +}; + +/*! + Constructs a new key event transition with the given \a sourceState. +*/ +QKeyEventTransition::QKeyEventTransition(QState *sourceState) + : QEventTransition(*new QKeyEventTransitionPrivate, sourceState) +{ + Q_D(QKeyEventTransition); + d->transition = new QBasicKeyEventTransition(); +} + +/*! + Constructs a new key event transition for events of the given \a type for + the given \a object, with the given \a key and \a sourceState. +*/ +QKeyEventTransition::QKeyEventTransition(QObject *object, QEvent::Type type, + int key, QState *sourceState) + : QEventTransition(*new QKeyEventTransitionPrivate, object, type, sourceState) +{ + Q_D(QKeyEventTransition); + d->transition = new QBasicKeyEventTransition(type, key); +} + +/*! + Constructs a new key event transition for events of the given \a type for + the given \a object, with the given \a key, \a targets and \a sourceState. +*/ +QKeyEventTransition::QKeyEventTransition(QObject *object, QEvent::Type type, + int key, const QList &targets, + QState *sourceState) + : QEventTransition(*new QKeyEventTransitionPrivate, object, type, targets, sourceState) +{ + Q_D(QKeyEventTransition); + d->transition = new QBasicKeyEventTransition(type, key); +} + +/*! + Destroys this key event transition. +*/ +QKeyEventTransition::~QKeyEventTransition() +{ + Q_D(QKeyEventTransition); + delete d->transition; +} + +/*! + Returns the key that this key event transition checks for. +*/ +int QKeyEventTransition::key() const +{ + Q_D(const QKeyEventTransition); + return d->transition->key(); +} + +/*! + Sets the key that this key event transition will check for. +*/ +void QKeyEventTransition::setKey(int key) +{ + Q_D(QKeyEventTransition); + d->transition->setKey(key); +} + +/*! + Returns the keyboard modifiers mask that this key event transition checks + for. +*/ +Qt::KeyboardModifiers QKeyEventTransition::modifiersMask() const +{ + Q_D(const QKeyEventTransition); + return d->transition->modifiersMask(); +} + +/*! + Sets the keyboard \a modifiers mask that this key event transition will + check for. +*/ +void QKeyEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask) +{ + Q_D(QKeyEventTransition); + d->transition->setModifiersMask(modifiersMask); +} + +/*! + \reimp +*/ +bool QKeyEventTransition::eventTest(QEvent *event) +{ + Q_D(const QKeyEventTransition); + if (!QEventTransition::eventTest(event)) + return false; + QWrappedEvent *we = static_cast(event); + d->transition->setEventType(we->event()->type()); + return QAbstractTransitionPrivate::get(d->transition)->callEventTest(we->event()); +} + +/*! + \reimp +*/ +void QKeyEventTransition::onTransition(QEvent *event) +{ + QEventTransition::onTransition(event); +} + +QT_END_NAMESPACE diff --git a/src/gui/statemachine/qkeyeventtransition.h b/src/gui/statemachine/qkeyeventtransition.h new file mode 100644 index 0000000..3c8295f --- /dev/null +++ b/src/gui/statemachine/qkeyeventtransition.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QKEYEVENTTRANSITION_H +#define QKEYEVENTTRANSITION_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QKeyEventTransitionPrivate; +class Q_GUI_EXPORT QKeyEventTransition : public QEventTransition +{ + Q_OBJECT + Q_PROPERTY(int key READ key WRITE setKey) + Q_PROPERTY(Qt::KeyboardModifiers modifiersMask READ modifiersMask WRITE setModifiersMask) +public: + QKeyEventTransition(QState *sourceState = 0); + QKeyEventTransition(QObject *object, QEvent::Type type, int key, + QState *sourceState = 0); + QKeyEventTransition(QObject *object, QEvent::Type type, int key, + const QList &targets, + QState *sourceState = 0); + ~QKeyEventTransition(); + + int key() const; + void setKey(int key); + + Qt::KeyboardModifiers modifiersMask() const; + void setModifiersMask(Qt::KeyboardModifiers modifiers); + +protected: + void onTransition(QEvent *event); + bool eventTest(QEvent *event); + +private: + Q_DISABLE_COPY(QKeyEventTransition) + Q_DECLARE_PRIVATE(QKeyEventTransition) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/gui/statemachine/qmouseeventtransition.cpp b/src/gui/statemachine/qmouseeventtransition.cpp new file mode 100644 index 0000000..e4e18eb --- /dev/null +++ b/src/gui/statemachine/qmouseeventtransition.cpp @@ -0,0 +1,216 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmouseeventtransition.h" +#include "qbasicmouseeventtransition_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QMouseEventTransition + + \brief The QMouseEventTransition class provides a transition for mouse events. + + \since 4.6 + \ingroup statemachine + + QMouseEventTransition is part of \l{The State Machine Framework}. + + \sa QState::addTransition() +*/ + +/*! + \property QMouseEventTransition::button + + \brief the button that this mouse event transition is associated with +*/ + +/*! + \property QMouseEventTransition::modifiersMask + + \brief the keyboard modifiers mask that this mouse event transition checks for +*/ + +class QMouseEventTransitionPrivate : public QEventTransitionPrivate +{ + Q_DECLARE_PUBLIC(QMouseEventTransition) +public: + QMouseEventTransitionPrivate(); + + QBasicMouseEventTransition *transition; +}; + +QMouseEventTransitionPrivate::QMouseEventTransitionPrivate() +{ +} + +/*! + Constructs a new mouse event transition with the given \a sourceState. +*/ +QMouseEventTransition::QMouseEventTransition(QState *sourceState) + : QEventTransition(*new QMouseEventTransitionPrivate, sourceState) +{ + Q_D(QMouseEventTransition); + d->transition = new QBasicMouseEventTransition(); +} + +/*! + Constructs a new mouse event transition for events of the given \a type for + the given \a object, with the given \a button and \a sourceState. +*/ +QMouseEventTransition::QMouseEventTransition(QObject *object, QEvent::Type type, + Qt::MouseButton button, + QState *sourceState) + : QEventTransition(*new QMouseEventTransitionPrivate, object, type, sourceState) +{ + Q_D(QMouseEventTransition); + d->transition = new QBasicMouseEventTransition(type, button); +} + +/*! + Constructs a new mouse event transition for events of the given \a type for + the given \a object, with the given \a button, \a targets and \a + sourceState. +*/ +QMouseEventTransition::QMouseEventTransition(QObject *object, QEvent::Type type, + Qt::MouseButton button, + const QList &targets, + QState *sourceState) + : QEventTransition(*new QMouseEventTransitionPrivate, object, type, targets, sourceState) +{ + Q_D(QMouseEventTransition); + d->transition = new QBasicMouseEventTransition(type, button); +} + +/*! + Destroys this mouse event transition. +*/ +QMouseEventTransition::~QMouseEventTransition() +{ + Q_D(QMouseEventTransition); + delete d->transition; +} + +/*! + Returns the button that this mouse event transition checks for. +*/ +Qt::MouseButton QMouseEventTransition::button() const +{ + Q_D(const QMouseEventTransition); + return d->transition->button(); +} + +/*! + Sets the \a button that this mouse event transition will check for. +*/ +void QMouseEventTransition::setButton(Qt::MouseButton button) +{ + Q_D(QMouseEventTransition); + d->transition->setButton(button); +} + +/*! + Returns the keyboard modifiers mask that this mouse event transition checks + for. +*/ +Qt::KeyboardModifiers QMouseEventTransition::modifiersMask() const +{ + Q_D(const QMouseEventTransition); + return d->transition->modifiersMask(); +} + +/*! + Sets the keyboard \a modifiers mask that this mouse event transition will + check for. +*/ +void QMouseEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask) +{ + Q_D(QMouseEventTransition); + d->transition->setModifiersMask(modifiersMask); +} + +/*! + Returns the path for this mouse event transition. +*/ +QPainterPath QMouseEventTransition::path() const +{ + Q_D(const QMouseEventTransition); + return d->transition->path(); +} + +/*! + Sets the \a path for this mouse event transition. + If a valid path has been set, the transition will only trigger if the mouse + event position (QMouseEvent::pos()) is inside the path. + + \sa QPainterPath::contains() +*/ +void QMouseEventTransition::setPath(const QPainterPath &path) +{ + Q_D(QMouseEventTransition); + d->transition->setPath(path); +} + +/*! + \reimp +*/ +bool QMouseEventTransition::eventTest(QEvent *event) +{ + Q_D(const QMouseEventTransition); + if (!QEventTransition::eventTest(event)) + return false; + QWrappedEvent *we = static_cast(event); + d->transition->setEventType(we->event()->type()); + return QAbstractTransitionPrivate::get(d->transition)->callEventTest(we->event()); +} + +/*! + \reimp +*/ +void QMouseEventTransition::onTransition(QEvent *event) +{ + QEventTransition::onTransition(event); +} + +QT_END_NAMESPACE diff --git a/src/gui/statemachine/qmouseeventtransition.h b/src/gui/statemachine/qmouseeventtransition.h new file mode 100644 index 0000000..3f5f3ac --- /dev/null +++ b/src/gui/statemachine/qmouseeventtransition.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMOUSEEVENTTRANSITION_H +#define QMOUSEEVENTTRANSITION_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Core) + +class QMouseEventTransitionPrivate; +class QPainterPath; +class Q_GUI_EXPORT QMouseEventTransition : public QEventTransition +{ + Q_OBJECT + Q_PROPERTY(Qt::MouseButton button READ button WRITE setButton) + Q_PROPERTY(Qt::KeyboardModifiers modifiersMask READ modifiersMask WRITE setModifiersMask) +public: + QMouseEventTransition(QState *sourceState = 0); + QMouseEventTransition(QObject *object, QEvent::Type type, + Qt::MouseButton button, QState *sourceState = 0); + QMouseEventTransition(QObject *object, QEvent::Type type, + Qt::MouseButton button, + const QList &targets, + QState *sourceState = 0); + ~QMouseEventTransition(); + + Qt::MouseButton button() const; + void setButton(Qt::MouseButton button); + + Qt::KeyboardModifiers modifiersMask() const; + void setModifiersMask(Qt::KeyboardModifiers modifiers); + + QPainterPath path() const; + void setPath(const QPainterPath &path); + +protected: + void onTransition(QEvent *event); + bool eventTest(QEvent *event); + +private: + Q_DISABLE_COPY(QMouseEventTransition) + Q_DECLARE_PRIVATE(QMouseEventTransition) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/gui/statemachine/statemachine.pri b/src/gui/statemachine/statemachine.pri new file mode 100644 index 0000000..2eb1e05 --- /dev/null +++ b/src/gui/statemachine/statemachine.pri @@ -0,0 +1,13 @@ +SOURCES += $$PWD/qguistatemachine.cpp +!contains(DEFINES, QT_NO_STATEMACHINE_EVENTFILTER) { + HEADERS += \ + $$PWD/qkeyeventtransition.h \ + $$PWD/qmouseeventtransition.h \ + $$PWD/qbasickeyeventtransition_p.h \ + $$PWD/qbasicmouseeventtransition_p.h + SOURCES += \ + $$PWD/qkeyeventtransition.cpp \ + $$PWD/qmouseeventtransition.cpp \ + $$PWD/qbasickeyeventtransition.cpp \ + $$PWD/qbasicmouseeventtransition.cpp +} diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 714e19d..316a695 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -75,6 +75,7 @@ SUBDIRS += bic \ qaction \ qactiongroup \ qalgorithms \ + qanimationgroup \ qapplication \ qatomicint \ qatomicpointer \ @@ -214,6 +215,7 @@ SUBDIRS += bic \ qpainter \ qpainterpath \ qpalette \ + qparallelanimationgroup \ qpathclipper \ qpen \ qpicture \ @@ -229,6 +231,7 @@ SUBDIRS += bic \ qprocess \ qprogressbar \ qprogressdialog \ + qpropertyanimation \ qpushbutton \ qqueue \ qradiobutton \ @@ -256,6 +259,7 @@ SUBDIRS += bic \ qscrollarea \ qsemaphore \ qsharedpointer \ + qsequentialanimationgroup \ qset \ qsettings \ qshortcut \ @@ -289,6 +293,7 @@ SUBDIRS += bic \ qstackedwidget \ qstandarditem \ qstandarditemmodel \ + qstate \ qstatusbar \ qstl \ qstring \ @@ -342,6 +347,7 @@ SUBDIRS += bic \ qtranslator \ qtransform \ qtransformedscreen \ + qtransition \ qtreeview \ qtreewidget \ qtreewidgetitemiterator \ diff --git a/tests/auto/qanimationgroup/qanimationgroup.pro b/tests/auto/qanimationgroup/qanimationgroup.pro new file mode 100644 index 0000000..97d33dd --- /dev/null +++ b/tests/auto/qanimationgroup/qanimationgroup.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT = core gui +SOURCES += tst_qanimationgroup.cpp + + diff --git a/tests/auto/qanimationgroup/tst_qanimationgroup.cpp b/tests/auto/qanimationgroup/tst_qanimationgroup.cpp new file mode 100644 index 0000000..2952a39 --- /dev/null +++ b/tests/auto/qanimationgroup/tst_qanimationgroup.cpp @@ -0,0 +1,413 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include + +//TESTED_CLASS=QAnimationGroup +//TESTED_FILES= + +Q_DECLARE_METATYPE(QAbstractAnimation::State) + +class tst_QAnimationGroup : public QObject +{ + Q_OBJECT +public: + tst_QAnimationGroup(); + virtual ~tst_QAnimationGroup(); + +public Q_SLOTS: + void init(); + void cleanup(); + +private slots: + void construction(); + void emptyGroup(); + void setCurrentTime(); + void statesAndSignals(); + void setParentAutoAdd(); + void beginNestedGroup(); + void addChildTwice(); + void loopWithoutStartValue(); +}; + +tst_QAnimationGroup::tst_QAnimationGroup() +{ +} + +tst_QAnimationGroup::~tst_QAnimationGroup() +{ +} + +void tst_QAnimationGroup::init() +{ + qRegisterMetaType("QAbstractAnimation::State"); +} + +void tst_QAnimationGroup::cleanup() +{ +} + +void tst_QAnimationGroup::construction() +{ + QSequentialAnimationGroup animationgroup; +} + +class AnimationObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue) +public: + AnimationObject(int startValue = 0) + : v(startValue) + { } + + int value() const { return v; } + void setValue(int value) { v = value; } + + int v; +}; + +class TestAnimation : public QVariantAnimation +{ + Q_OBJECT +public: + virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)}; + virtual void updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) + { + Q_UNUSED(oldState) + Q_UNUSED(newState) + }; +}; + +class UncontrolledAnimation : public QPropertyAnimation +{ + Q_OBJECT +public: + UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0) + : QPropertyAnimation(target, propertyName, parent), id(0) + { + setDuration(250); + } + + int duration() const { return -1; /* not time driven */ } + +protected: + void timerEvent(QTimerEvent *event) + { + if (event->timerId() == id) + stop(); + } + + void updateRunning(bool running) + { + if (running) { + id = startTimer(500); + } else { + killTimer(id); + id = 0; + } + } + +private: + int id; +}; + +void tst_QAnimationGroup::emptyGroup() +{ + QSequentialAnimationGroup group; + QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + group.start(); + + QCOMPARE(groupStateChangedSpy.count(), 2); + + QCOMPARE(qVariantValue(groupStateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(groupStateChangedSpy.at(1).at(1)), + QAnimationGroup::Stopped); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + + QTest::ignoreMessage(QtWarningMsg, "QAbstractAnimation::pause: Cannot pause a stopped animation"); + group.pause(); + + QCOMPARE(groupStateChangedSpy.count(), 2); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + + group.start(); + + QCOMPARE(qVariantValue(groupStateChangedSpy.at(2).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(groupStateChangedSpy.at(3).at(1)), + QAnimationGroup::Stopped); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + + group.stop(); + + QCOMPARE(groupStateChangedSpy.count(), 4); + QCOMPARE(group.state(), QAnimationGroup::Stopped); +} + +void tst_QAnimationGroup::setCurrentTime() +{ + AnimationObject s_o1; + AnimationObject s_o2; + AnimationObject s_o3; + AnimationObject p_o1; + AnimationObject p_o2; + AnimationObject p_o3; + AnimationObject t_o1; + AnimationObject t_o2; + + // sequence operating on same object/property + QSequentialAnimationGroup *sequence = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); + a2_s_o1->setLoopCount(3); + sequence->addAnimation(a1_s_o1); + sequence->addAnimation(a2_s_o1); + sequence->addAnimation(a3_s_o1); + + // sequence operating on different object/properties + QAnimationGroup *sequence2 = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); + QVariantAnimation *a1_s_o3 = new QPropertyAnimation(&s_o3, "value"); + sequence2->addAnimation(a1_s_o2); + sequence2->addAnimation(a1_s_o3); + + // parallel operating on different object/properties + QAnimationGroup *parallel = new QParallelAnimationGroup(); + QVariantAnimation *a1_p_o1 = new QPropertyAnimation(&p_o1, "value"); + QVariantAnimation *a1_p_o2 = new QPropertyAnimation(&p_o2, "value"); + QVariantAnimation *a1_p_o3 = new QPropertyAnimation(&p_o3, "value"); + a1_p_o2->setLoopCount(3); + parallel->addAnimation(a1_p_o1); + parallel->addAnimation(a1_p_o2); + parallel->addAnimation(a1_p_o3); + + UncontrolledAnimation *notTimeDriven = new UncontrolledAnimation(&t_o1, "value"); + QCOMPARE(notTimeDriven->totalDuration(), -1); + + QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value"); + loopsForever->setLoopCount(-1); + QCOMPARE(loopsForever->totalDuration(), -1); + + QParallelAnimationGroup group; + group.addAnimation(sequence); + group.addAnimation(sequence2); + group.addAnimation(parallel); + group.addAnimation(notTimeDriven); + group.addAnimation(loopsForever); + + // Current time = 1 + group.setCurrentTime(1); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(sequence->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(parallel->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_p_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_p_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_p_o3->state(), QAnimationGroup::Stopped); + QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); + QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); + + QCOMPARE(group.currentTime(), 1); + QCOMPARE(sequence->currentTime(), 1); + QCOMPARE(a1_s_o1->currentTime(), 1); + QCOMPARE(a2_s_o1->currentTime(), 0); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 1); + QCOMPARE(a1_s_o3->currentTime(), 0); + QCOMPARE(a1_p_o1->currentTime(), 1); + QCOMPARE(a1_p_o2->currentTime(), 1); + QCOMPARE(a1_p_o3->currentTime(), 1); + QCOMPARE(notTimeDriven->currentTime(), 1); + QCOMPARE(loopsForever->currentTime(), 1); + + // Current time = 250 + group.setCurrentTime(250); + QCOMPARE(group.currentTime(), 250); + QCOMPARE(sequence->currentTime(), 250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 0); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(a1_s_o3->currentTime(), 0); + QCOMPARE(a1_p_o1->currentTime(), 250); + QCOMPARE(a1_p_o2->currentTime(), 0); + QCOMPARE(a1_p_o2->currentLoop(), 1); + QCOMPARE(a1_p_o3->currentTime(), 250); + QCOMPARE(notTimeDriven->currentTime(), 250); + QCOMPARE(loopsForever->currentTime(), 0); + QCOMPARE(loopsForever->currentLoop(), 1); + QCOMPARE(sequence->currentAnimation(), a2_s_o1); + + // Current time = 251 + group.setCurrentTime(251); + QCOMPARE(group.currentTime(), 251); + QCOMPARE(sequence->currentTime(), 251); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 1); + QCOMPARE(a2_s_o1->currentLoop(), 0); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(sequence2->currentTime(), 251); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(a1_s_o3->currentTime(), 1); + QCOMPARE(a1_p_o1->currentTime(), 250); + QCOMPARE(a1_p_o2->currentTime(), 1); + QCOMPARE(a1_p_o2->currentLoop(), 1); + QCOMPARE(a1_p_o3->currentTime(), 250); + QCOMPARE(notTimeDriven->currentTime(), 251); + QCOMPARE(loopsForever->currentTime(), 1); + QCOMPARE(sequence->currentAnimation(), a2_s_o1); +} + +void tst_QAnimationGroup::statesAndSignals() +{ +} + +void tst_QAnimationGroup::setParentAutoAdd() +{ + QParallelAnimationGroup group; + QVariantAnimation *animation = new QPropertyAnimation(&group); + QCOMPARE(animation->group(), &group); +} + +void tst_QAnimationGroup::beginNestedGroup() +{ + QAnimationGroup *subGroup; + QAnimationGroup *parent = new QParallelAnimationGroup(); + + for (int i = 0; i < 10; ++i) { + if (i & 1) + subGroup = new QParallelAnimationGroup(parent); + else + subGroup = new QSequentialAnimationGroup(parent); + + QCOMPARE(parent->animationCount(), 1); + QAnimationGroup *child = static_cast(parent->animationAt(0)); + + QCOMPARE(child->parent(), static_cast(parent)); + if (i & 1) + QVERIFY(qobject_cast (child)); + else + QVERIFY(qobject_cast (child)); + + parent = child; + } +} + +void tst_QAnimationGroup::addChildTwice() +{ + QPropertyAnimation *subGroup; + QPropertyAnimation *subGroup2; + QAnimationGroup *parent = new QSequentialAnimationGroup(); + + subGroup = new QPropertyAnimation(); + subGroup->setParent(parent); + parent->addAnimation(subGroup); + QCOMPARE(parent->animationCount(), 1); + + parent->clearAnimations(); + + QCOMPARE(parent->animationCount(), 0); + + // adding the same item twice to a group will remove the item from its current position + // and append it to the end + subGroup = new QPropertyAnimation(parent); + subGroup2 = new QPropertyAnimation(parent); + + QCOMPARE(parent->animationCount(), 2); + QCOMPARE(parent->animationAt(0), subGroup); + QCOMPARE(parent->animationAt(1), subGroup2); + + parent->addAnimation(subGroup); + + QCOMPARE(parent->animationCount(), 2); + QCOMPARE(parent->animationAt(0), subGroup2); + QCOMPARE(parent->animationAt(1), subGroup); + + delete parent; +} + +void tst_QAnimationGroup::loopWithoutStartValue() +{ + QAnimationGroup *parent = new QSequentialAnimationGroup(); + QObject o; + o.setProperty("ole", 0); + QCOMPARE(o.property("ole").toInt(), 0); + + QPropertyAnimation anim1(&o, "ole"); + anim1.setEndValue(-50); + anim1.setDuration(100); + + QPropertyAnimation anim2(&o, "ole"); + anim2.setEndValue(50); + anim2.setDuration(100); + + parent->addAnimation(&anim1); + parent->addAnimation(&anim2); + + parent->setLoopCount(-1); + parent->start(); + + QVERIFY(anim1.startValue().isNull()); + QCOMPARE(anim1.currentValue().toInt(), 0); + QCOMPARE(parent->currentLoop(), 0); + + parent->setCurrentTime(200); + QCOMPARE(parent->currentLoop(), 1); + QCOMPARE(anim1.currentValue().toInt(), 50); + parent->stop(); +} + +QTEST_MAIN(tst_QAnimationGroup) +#include "tst_qanimationgroup.moc" diff --git a/tests/auto/qeasingcurve/qeasingcurve.pro b/tests/auto/qeasingcurve/qeasingcurve.pro new file mode 100644 index 0000000..2b66081 --- /dev/null +++ b/tests/auto/qeasingcurve/qeasingcurve.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +QT = core +SOURCES += tst_qeasingcurve.cpp diff --git a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp new file mode 100644 index 0000000..8d42e5e --- /dev/null +++ b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp @@ -0,0 +1,487 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include + +#if QT_VERSION < 0x040200 +QTEST_NOOP_MAIN +#else + +#include + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QEasingCurve : public QObject { + Q_OBJECT + +public: + tst_QEasingCurve(); + virtual ~tst_QEasingCurve(); + +public Q_SLOTS: + void init(); + void cleanup(); + +private slots: + void type(); + void propertyDefaults(); + void valueForProgress_data(); + void valueForProgress(); + void setCustomType(); + void operators(); + +protected: +}; + +tst_QEasingCurve::tst_QEasingCurve() +{ +} + +tst_QEasingCurve::~tst_QEasingCurve() +{ +} + +void tst_QEasingCurve::init() +{ +} + +void tst_QEasingCurve::cleanup() +{ +} +#include + +void tst_QEasingCurve::type() +{ + { + QEasingCurve curve(QEasingCurve::Linear); + QCOMPARE(curve.period(), 0.3); + QCOMPARE(curve.amplitude(), 1.0); + + curve.setPeriod(5); + curve.setAmplitude(3); + QCOMPARE(curve.period(), 5.0); + QCOMPARE(curve.amplitude(), 3.0); + + curve.setType(QEasingCurve::InElastic); + QCOMPARE(curve.period(), 5.0); + QCOMPARE(curve.amplitude(), 3.0); + } + + { + QEasingCurve curve(QEasingCurve::InElastic); + QCOMPARE(curve.period(), 0.3); + QCOMPARE(curve.amplitude(), 1.0); + curve.setAmplitude(2); + QCOMPARE(curve.type(), QEasingCurve::InElastic); + curve.setType(QEasingCurve::Linear); + } + + { + // check bounaries + QEasingCurve curve(QEasingCurve::InCubic); + QTest::ignoreMessage(QtWarningMsg, "QEasingCurve: Invalid curve type 9999"); + curve.setType((QEasingCurve::Type)9999); + QCOMPARE(curve.type(), QEasingCurve::InCubic); + QTest::ignoreMessage(QtWarningMsg, "QEasingCurve: Invalid curve type -9999"); + curve.setType((QEasingCurve::Type)-9999); + QCOMPARE(curve.type(), QEasingCurve::InCubic); + QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QEasingCurve: Invalid curve type %1") + .arg(QEasingCurve::NCurveTypes).toLatin1().constData()); + curve.setType(QEasingCurve::NCurveTypes); + QCOMPARE(curve.type(), QEasingCurve::InCubic); + QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QEasingCurve: Invalid curve type %1") + .arg(QEasingCurve::Custom).toLatin1().constData()); + curve.setType(QEasingCurve::Custom); + QCOMPARE(curve.type(), QEasingCurve::InCubic); + QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QEasingCurve: Invalid curve type %1") + .arg(-1).toLatin1().constData()); + curve.setType((QEasingCurve::Type)-1); + QCOMPARE(curve.type(), QEasingCurve::InCubic); + curve.setType(QEasingCurve::Linear); + QCOMPARE(curve.type(), QEasingCurve::Linear); + curve.setType(QEasingCurve::CosineCurve); + QCOMPARE(curve.type(), QEasingCurve::CosineCurve); + } +} + +void tst_QEasingCurve::propertyDefaults() +{ + { + // checks if the defaults are correct, but also demonstrates a weakness with the API. + QEasingCurve curve(QEasingCurve::InElastic); + QCOMPARE(curve.period(), 0.3); + QCOMPARE(curve.amplitude(), 1.0); + QCOMPARE(curve.overshoot(), qreal(1.70158f)); + curve.setType(QEasingCurve::InBounce); + QCOMPARE(curve.period(), 0.3); + QCOMPARE(curve.amplitude(), 1.0); + QCOMPARE(curve.overshoot(), qreal(1.70158f)); + curve.setType(QEasingCurve::Linear); + QCOMPARE(curve.period(), 0.3); + QCOMPARE(curve.amplitude(), 1.0); + QCOMPARE(curve.overshoot(), qreal(1.70158f)); + curve.setType(QEasingCurve::InElastic); + QCOMPARE(curve.period(), 0.3); + QCOMPARE(curve.amplitude(), 1.0); + QCOMPARE(curve.overshoot(), qreal(1.70158f)); + curve.setPeriod(0.4); + curve.setAmplitude(0.6); + curve.setOvershoot(1.0); + curve.setType(QEasingCurve::Linear); + QCOMPARE(curve.period(), 0.4); + QCOMPARE(curve.amplitude(), 0.6); + QCOMPARE(curve.overshoot(), 1.0); + curve.setType(QEasingCurve::InElastic); + QCOMPARE(curve.period(), 0.4); + QCOMPARE(curve.amplitude(), 0.6); + QCOMPARE(curve.overshoot(), 1.0); + } +} + +typedef QList IntList; +Q_DECLARE_METATYPE(IntList) + +void tst_QEasingCurve::valueForProgress_data() +{ + QTest::addColumn("type"); + QTest::addColumn("at"); + QTest::addColumn("expected"); + // automatically generated. + // note that values are scaled from range [0,1] to range [0, 100] in order to store them as + // integer values and avoid fp inaccuracies + + QTest::newRow("Linear") << int(QEasingCurve::Linear) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100); + + QTest::newRow("InQuad") << int(QEasingCurve::InQuad) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 1 << 4 << 9 << 16 << 25 << 36 << 48 << 64 << 81 << 100); + + QTest::newRow("OutQuad") << int(QEasingCurve::OutQuad) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 19 << 36 << 51 << 64 << 75 << 84 << 90 << 96 << 99 << 100); + + QTest::newRow("InOutQuad") << int(QEasingCurve::InOutQuad) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 2 << 8 << 18 << 32 << 50 << 68 << 82 << 92 << 98 << 100); + + QTest::newRow("OutInQuad") << int(QEasingCurve::OutInQuad) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 18 << 32 << 42 << 48 << 50 << 52 << 57 << 68 << 82 << 100); + + QTest::newRow("InCubic") << int(QEasingCurve::InCubic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 2 << 6 << 12 << 21 << 34 << 51 << 72 << 100); + + QTest::newRow("OutCubic") << int(QEasingCurve::OutCubic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 27 << 48 << 65 << 78 << 87 << 93 << 97 << 99 << 99 << 100); + + QTest::newRow("InOutCubic") << int(QEasingCurve::InOutCubic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 3 << 10 << 25 << 50 << 74 << 89 << 96 << 99 << 100); + + QTest::newRow("OutInCubic") << int(QEasingCurve::OutInCubic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 24 << 39 << 46 << 49 << 50 << 50 << 53 << 60 << 75 << 100); + + QTest::newRow("InQuart") << int(QEasingCurve::InQuart) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 0 << 2 << 6 << 12 << 24 << 40 << 65 << 100); + + QTest::newRow("OutQuart") << int(QEasingCurve::OutQuart) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 34 << 59 << 75 << 87 << 93 << 97 << 99 << 99 << 99 << 100); + + QTest::newRow("InOutQuart") << int(QEasingCurve::InOutQuart) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 1 << 6 << 20 << 50 << 79 << 93 << 98 << 99 << 100); + + QTest::newRow("OutInQuart") << int(QEasingCurve::OutInQuart) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 29 << 43 << 48 << 49 << 50 << 50 << 51 << 56 << 70 << 100); + + QTest::newRow("InQuint") << int(QEasingCurve::InQuint) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 0 << 1 << 3 << 7 << 16 << 32 << 59 << 100); + + QTest::newRow("OutQuint") << int(QEasingCurve::OutQuint) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 40 << 67 << 83 << 92 << 96 << 98 << 99 << 99 << 99 << 100); + + QTest::newRow("InOutQuint") << int(QEasingCurve::InOutQuint) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 3 << 16 << 50 << 83 << 96 << 99 << 99 << 100); + + QTest::newRow("OutInQuint") << int(QEasingCurve::OutInQuint) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 33 << 46 << 49 << 49 << 50 << 50 << 50 << 53 << 66 << 100); + + QTest::newRow("InSine") << int(QEasingCurve::InSine) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 1 << 4 << 10 << 19 << 29 << 41 << 54 << 69 << 84 << 100); + + QTest::newRow("OutSine") << int(QEasingCurve::OutSine) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 15 << 30 << 45 << 58 << 70 << 80 << 89 << 95 << 98 << 100); + + QTest::newRow("InOutSine") << int(QEasingCurve::InOutSine) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 2 << 9 << 20 << 34 << 49 << 65 << 79 << 90 << 97 << 100); + + QTest::newRow("OutInSine") << int(QEasingCurve::OutInSine) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 15 << 29 << 40 << 47 << 50 << 52 << 59 << 70 << 84 << 100); + + QTest::newRow("InExpo") << int(QEasingCurve::InExpo) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 0 << 1 << 3 << 6 << 12 << 24 << 49 << 100); + + QTest::newRow("OutExpo") << int(QEasingCurve::OutExpo) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 50 << 75 << 87 << 93 << 96 << 98 << 99 << 99 << 99 << 100); + + QTest::newRow("InOutExpo") << int(QEasingCurve::InOutExpo) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 3 << 12 << 50 << 87 << 96 << 99 << 99 << 100); + + QTest::newRow("OutInExpo") << int(QEasingCurve::OutInExpo) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 37 << 46 << 49 << 49 << 50 << 50 << 50 << 53 << 62 << 100); + + QTest::newRow("InCirc") << int(QEasingCurve::InCirc) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 2 << 4 << 8 << 13 << 19 << 28 << 40 << 56 << 100); + + QTest::newRow("OutCirc") << int(QEasingCurve::OutCirc) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 43 << 59 << 71 << 80 << 86 << 91 << 95 << 97 << 99 << 100); + + QTest::newRow("InOutCirc") << int(QEasingCurve::InOutCirc) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 1 << 4 << 9 << 20 << 50 << 80 << 89 << 95 << 98 << 100); + + QTest::newRow("OutInCirc") << int(QEasingCurve::OutInCirc) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 29 << 40 << 45 << 48 << 50 << 51 << 54 << 60 << 70 << 100); + + QTest::newRow("InElastic") << int(QEasingCurve::InElastic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << 0 << 1 << -1 << -3 << 12 << -12 << -25 << 100); + + QTest::newRow("OutElastic") << int(QEasingCurve::OutElastic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 125 << 112 << 87 << 103 << 101 << 98 << 100 << 100 << 99 << 100); + + QTest::newRow("InOutElastic") << int(QEasingCurve::InOutElastic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 0 << 0 << -1 << -6 << 50 << 106 << 101 << 99 << 100 << 100); + + QTest::newRow("OutInElastic") << int(QEasingCurve::OutInElastic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 37 << 56 << 49 << 49 << 50 << 49 << 50 << 53 << 24 << 100); + + QTest::newRow("InBack") << int(QEasingCurve::InBack) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << -1 << -4 << -8 << -9 << -8 << -2 << 9 << 29 << 59 << 100); + + QTest::newRow("OutBack") << int(QEasingCurve::OutBack) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 40 << 70 << 90 << 102 << 108 << 109 << 108 << 104 << 101 << 100); + + QTest::newRow("InOutBack") << int(QEasingCurve::InOutBack) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << -3 << -9 << -7 << 8 << 50 << 91 << 107 << 109 << 103 << 100); + + QTest::newRow("OutInBack") << int(QEasingCurve::OutInBack) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 35 << 51 << 54 << 52 << 50 << 47 << 45 << 48 << 64 << 100); + + QTest::newRow("InBounce") << int(QEasingCurve::InBounce) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 1 << 6 << 6 << 22 << 23 << 9 << 31 << 69 << 92 << 100); + + QTest::newRow("OutBounce") << int(QEasingCurve::OutBounce) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 7 << 30 << 68 << 90 << 76 << 77 << 93 << 94 << 98 << 100); + + QTest::newRow("InOutBounce") << int(QEasingCurve::InOutBounce) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 3 << 11 << 4 << 34 << 50 << 65 << 95 << 88 << 97 << 100); + + QTest::newRow("OutInBounce") << int(QEasingCurve::OutInBounce) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 15 << 40 << 27 << 43 << 50 << 56 << 72 << 58 << 84 << 100); + + QTest::newRow("InCurve") << int(QEasingCurve::InCurve) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 2 << 10 << 23 << 37 << 50 << 60 << 70 << 80 << 90 << 100); + + QTest::newRow("OutCurve") << int(QEasingCurve::OutCurve) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 10 << 20 << 30 << 39 << 50 << 62 << 76 << 89 << 97 << 100); + + QTest::newRow("SineCurve") << int(QEasingCurve::SineCurve) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 0 << 9 << 34 << 65 << 90 << 100 << 90 << 65 << 34 << 9 << 0); + + QTest::newRow("CosineCurve") << int(QEasingCurve::CosineCurve) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (IntList() << 50 << 79 << 97 << 97 << 79 << 50 << 20 << 2 << 2 << 20 << 49); + +} + + +void tst_QEasingCurve::valueForProgress() +{ +#if 0 + // used to generate data tables... + QFile out; + out.open(stdout, QIODevice::WriteOnly); + for (int c = QEasingCurve::Linear; c < QEasingCurve::NCurveTypes - 1; ++c) { + QEasingCurve curve((QEasingCurve::Type)c); + QMetaObject mo = QEasingCurve::staticMetaObject; + QString strCurve = QLatin1String(mo.enumerator(mo.indexOfEnumerator("Type")).key(c)); + QString strInputs; + QString strOutputs; + + for (int t = 0; t <= 100; t+= 10) { + qreal ease = curve.valueForProgress(t/qreal(100)); + strInputs += QString::fromAscii(" << %1").arg(t); + strOutputs += QString::fromAscii(" << %1").arg(int(100*ease)); + + } + QString str = QString::fromAscii(" QTest::newRow(\"%1\") << int(QEasingCurve::%2)\n" + "\t\t << (IntList() %3)\n" + "\t\t << (IntList() %4);\n\n") + .arg(strCurve) + .arg(strCurve) + .arg(strInputs) + .arg(strOutputs); + out.write(str.toLatin1().constData()); + } + out.close(); + exit(1); +#else + QFETCH(int, type); + QFETCH(IntList, at); + QFETCH(IntList, expected); + + QEasingCurve curve((QEasingCurve::Type)type); + for (int i = 0; i < at.count(); ++i) { + qreal ease = curve.valueForProgress(at.at(i)/qreal(100)); + int ex = expected.at(i); + QCOMPARE(int(100*ease), ex); + } +#endif +} + +static qreal discreteEase(qreal progress) +{ + return qFloor(progress * 10) / qreal(10.0); +} + +void tst_QEasingCurve::setCustomType() +{ + QEasingCurve curve; + curve.setCustomType(&discreteEase); + QCOMPARE(curve.type(), QEasingCurve::Custom); + QCOMPARE(curve.valueForProgress(0.0), 0.0); + QCOMPARE(curve.valueForProgress(0.05), 0.0); + QCOMPARE(curve.valueForProgress(0.10), 0.1); + QCOMPARE(curve.valueForProgress(0.15), 0.1); + QCOMPARE(curve.valueForProgress(0.20), 0.2); + QCOMPARE(curve.valueForProgress(0.25), 0.2); + QCOMPARE(curve.valueForProgress(0.30), 0.3); + QCOMPARE(curve.valueForProgress(0.35), 0.3); + QCOMPARE(curve.valueForProgress(0.999999), 0.9); + + curve.setType(QEasingCurve::Linear); + QCOMPARE(curve.type(), QEasingCurve::Linear); + QCOMPARE(curve.valueForProgress(0.0), 0.0); + QCOMPARE(curve.valueForProgress(0.1), 0.1); + QCOMPARE(curve.valueForProgress(0.5), 0.5); + QCOMPARE(curve.valueForProgress(0.99), 0.99); +} + +void tst_QEasingCurve::operators() +{ + // operator= + QEasingCurve curve; + QEasingCurve curve2; + curve.setCustomType(&discreteEase); + curve2 = curve; + QCOMPARE(curve2.type(), QEasingCurve::Custom); + QCOMPARE(curve2.valueForProgress(0.0), 0.0); + QCOMPARE(curve2.valueForProgress(0.05), 0.0); + QCOMPARE(curve2.valueForProgress(0.15), 0.1); + QCOMPARE(curve2.valueForProgress(0.25), 0.2); + QCOMPARE(curve2.valueForProgress(0.35), 0.3); + QCOMPARE(curve2.valueForProgress(0.999999), 0.9); + + // operator== + curve.setType(QEasingCurve::InBack); + curve2 = curve; + curve2.setOvershoot(qreal(1.70158f)); + QCOMPARE(curve.overshoot(), curve2.overshoot()); + QVERIFY(curve2 == curve); + + curve.setOvershoot(3.0); + QVERIFY(curve2 != curve); + curve2.setOvershoot(3.0); + QVERIFY(curve2 == curve); + + curve2.setType(QEasingCurve::Linear); + QCOMPARE(curve.overshoot(), curve2.overshoot()); + QVERIFY(curve2 != curve); + curve2.setType(QEasingCurve::InBack); + QCOMPARE(curve.overshoot(), curve2.overshoot()); + QVERIFY(curve2 == curve); +} + + +QTEST_MAIN(tst_QEasingCurve) +#include "tst_qeasingcurve.moc" + +#endif //QT_VERSION diff --git a/tests/auto/qmake/testdata/bundle-spaces/some-file b/tests/auto/qmake/testdata/bundle-spaces/some-file index e69de29..9975dba 100644 --- a/tests/auto/qmake/testdata/bundle-spaces/some-file +++ b/tests/auto/qmake/testdata/bundle-spaces/some-file @@ -0,0 +1,6 @@ +all: + C:\git\qt-kinetic-animations\bin\qmake qdir.pro -o Makefile -spec win32-msvc2008 + nmake -f Makefile +first: all +qmake: + C:\git\qt-kinetic-animations\bin\qmake qdir.pro -o Makefile -spec win32-msvc2008 diff --git a/tests/auto/qparallelanimationgroup/qparallelanimationgroup.pro b/tests/auto/qparallelanimationgroup/qparallelanimationgroup.pro new file mode 100644 index 0000000..f2cacd3 --- /dev/null +++ b/tests/auto/qparallelanimationgroup/qparallelanimationgroup.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT = core gui +SOURCES += tst_qparallelanimationgroup.cpp + + diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp new file mode 100644 index 0000000..f2ab57a --- /dev/null +++ b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp @@ -0,0 +1,834 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include + +//TESTED_CLASS=QParallelAnimationGroup +//TESTED_FILES= + +Q_DECLARE_METATYPE(QAbstractAnimation::State) + +class tst_QParallelAnimationGroup : public QObject +{ + Q_OBJECT +public: + tst_QParallelAnimationGroup(); + virtual ~tst_QParallelAnimationGroup(); + +public Q_SLOTS: + void init(); + void cleanup(); + +private slots: + void construction(); + void setCurrentTime(); + void clearGroup(); + void propagateGroupUpdateToChildren(); + void updateChildrenWithRunningGroup(); + void deleteChildrenWithRunningGroup(); + void startChildrenWithStoppedGroup(); + void stopGroupWithRunningChild(); + void startGroupWithRunningChild(); + void zeroDurationAnimation(); + void stopUncontrolledAnimations(); + void loopCount_data(); + void loopCount(); + void autoAdd(); +}; + +tst_QParallelAnimationGroup::tst_QParallelAnimationGroup() +{ +} + +tst_QParallelAnimationGroup::~tst_QParallelAnimationGroup() +{ +} + +void tst_QParallelAnimationGroup::init() +{ + qRegisterMetaType("QAbstractAnimation::State"); +} + +void tst_QParallelAnimationGroup::cleanup() +{ +} + +void tst_QParallelAnimationGroup::construction() +{ + QParallelAnimationGroup animationgroup; +} + +class AnimationObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue) +public: + AnimationObject(int startValue = 0) + : v(startValue) + { } + + int value() const { return v; } + void setValue(int value) { v = value; } + + int v; +}; + +class TestAnimation : public QVariantAnimation +{ + Q_OBJECT +public: + virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)}; + virtual void updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) + { + Q_UNUSED(oldState) + Q_UNUSED(newState) + }; +}; + +class TestAnimation2 : public QVariantAnimation +{ + Q_OBJECT +public: + TestAnimation2(QAbstractAnimation *animation) : QVariantAnimation(animation) {} + TestAnimation2(int duration, QAbstractAnimation *animation) : QVariantAnimation(animation), m_duration(duration) {} + + virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)}; + virtual void updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) + { + Q_UNUSED(oldState) + Q_UNUSED(newState) + }; + + virtual int duration() const { + return m_duration; + } +private: + int m_duration; +}; + +class UncontrolledAnimation : public QPropertyAnimation +{ + Q_OBJECT +public: + UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0) + : QPropertyAnimation(target, propertyName, parent), id(0) + { + setDuration(250); + } + + int duration() const { return -1; /* not time driven */ } + +protected: + void timerEvent(QTimerEvent *event) + { + if (event->timerId() == id) + stop(); + } + + void updateRunning(bool running) + { + if (running) { + id = startTimer(500); + } else { + killTimer(id); + id = 0; + } + } + +private: + int id; +}; + +void tst_QParallelAnimationGroup::setCurrentTime() +{ + AnimationObject p_o1; + AnimationObject p_o2; + AnimationObject p_o3; + AnimationObject t_o1; + AnimationObject t_o2; + + // parallel operating on different object/properties + QAnimationGroup *parallel = new QParallelAnimationGroup(); + QVariantAnimation *a1_p_o1 = new QPropertyAnimation(&p_o1, "value"); + QVariantAnimation *a1_p_o2 = new QPropertyAnimation(&p_o2, "value"); + QVariantAnimation *a1_p_o3 = new QPropertyAnimation(&p_o3, "value"); + a1_p_o2->setLoopCount(3); + parallel->addAnimation(a1_p_o1); + parallel->addAnimation(a1_p_o2); + parallel->addAnimation(a1_p_o3); + + UncontrolledAnimation *notTimeDriven = new UncontrolledAnimation(&t_o1, "value"); + QCOMPARE(notTimeDriven->totalDuration(), -1); + + QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value"); + loopsForever->setLoopCount(-1); + QCOMPARE(loopsForever->totalDuration(), -1); + + QParallelAnimationGroup group; + group.addAnimation(parallel); + group.addAnimation(notTimeDriven); + group.addAnimation(loopsForever); + + // Current time = 1 + group.setCurrentTime(1); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(parallel->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_p_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_p_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_p_o3->state(), QAnimationGroup::Stopped); + QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); + QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); + + QCOMPARE(group.currentTime(), 1); + QCOMPARE(a1_p_o1->currentTime(), 1); + QCOMPARE(a1_p_o2->currentTime(), 1); + QCOMPARE(a1_p_o3->currentTime(), 1); + QCOMPARE(notTimeDriven->currentTime(), 1); + QCOMPARE(loopsForever->currentTime(), 1); + + // Current time = 250 + group.setCurrentTime(250); + QCOMPARE(group.currentTime(), 250); + QCOMPARE(a1_p_o1->currentTime(), 250); + QCOMPARE(a1_p_o2->currentTime(), 0); + QCOMPARE(a1_p_o2->currentLoop(), 1); + QCOMPARE(a1_p_o3->currentTime(), 250); + QCOMPARE(notTimeDriven->currentTime(), 250); + QCOMPARE(loopsForever->currentTime(), 0); + QCOMPARE(loopsForever->currentLoop(), 1); + + // Current time = 251 + group.setCurrentTime(251); + QCOMPARE(group.currentTime(), 251); + QCOMPARE(a1_p_o1->currentTime(), 250); + QCOMPARE(a1_p_o2->currentTime(), 1); + QCOMPARE(a1_p_o2->currentLoop(), 1); + QCOMPARE(a1_p_o3->currentTime(), 250); + QCOMPARE(notTimeDriven->currentTime(), 251); + QCOMPARE(loopsForever->currentTime(), 1); +} + +void tst_QParallelAnimationGroup::clearGroup() +{ + QParallelAnimationGroup group; + + for (int i = 0; i < 10; ++i) { + new QParallelAnimationGroup(&group); + } + + QCOMPARE(group.animationCount(), 10); + + int count = group.animationCount(); + QPointer *children = new QPointer[count]; + for (int i = 0; i < count; ++i) { + QVERIFY(group.animationAt(i) != 0); + children[i] = group.animationAt(i); + } + + group.clearAnimations(); + QCOMPARE(group.animationCount(), 0); + QCOMPARE(group.currentTime(), 0); + for (int i = 0; i < count; ++i) + QCOMPARE(children[i], QPointer()); + + delete[] children; +} + +void tst_QParallelAnimationGroup::propagateGroupUpdateToChildren() +{ + // this test verifies if group state changes are updating its children correctly + QParallelAnimationGroup group; + + QObject o; + o.setProperty("ole", 42); + QCOMPARE(o.property("ole").toInt(), 42); + + QPropertyAnimation anim1(&o, "ole"); + anim1.setEndValue(43); + anim1.setDuration(100); + QVERIFY(!anim1.currentValue().isValid()); + QCOMPARE(anim1.currentValue().toInt(), 0); + QCOMPARE(o.property("ole").toInt(), 42); + + TestAnimation anim2; + anim2.setStartValue(0); + anim2.setEndValue(100); + anim2.setDuration(200); + + QVERIFY(anim2.currentValue().isValid()); + QCOMPARE(anim2.currentValue().toInt(), 0); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + + group.start(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Running); + + group.pause(); + + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(anim1.state(), QAnimationGroup::Paused); + QCOMPARE(anim2.state(), QAnimationGroup::Paused); + + group.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); +} + +void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup() +{ + // assert that its possible to modify a child's state directly while their group is running + QParallelAnimationGroup group; + + TestAnimation anim; + anim.setStartValue(0); + anim.setEndValue(100); + anim.setDuration(200); + + QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + QCOMPARE(groupStateChangedSpy.count(), 0); + QCOMPARE(childStateChangedSpy.count(), 0); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim.state(), QAnimationGroup::Stopped); + + group.addAnimation(&anim); + + group.start(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim.state(), QAnimationGroup::Running); + + QCOMPARE(groupStateChangedSpy.count(), 1); + QCOMPARE(childStateChangedSpy.count(), 1); + + QCOMPARE(qVariantValue(groupStateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(childStateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + + // starting directly a running child will not have any effect + anim.start(); + + QCOMPARE(groupStateChangedSpy.count(), 1); + QCOMPARE(childStateChangedSpy.count(), 1); + + anim.pause(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim.state(), QAnimationGroup::Paused); + + // in the animation stops directly, the group will still be running + anim.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim.state(), QAnimationGroup::Stopped); +} + +void tst_QParallelAnimationGroup::deleteChildrenWithRunningGroup() +{ + // test if children can be activated when their group is stopped + QParallelAnimationGroup group; + + QVariantAnimation *anim1 = new TestAnimation; + anim1->setStartValue(0); + anim1->setEndValue(100); + anim1->setDuration(200); + group.addAnimation(anim1); + + QCOMPARE(group.duration(), anim1->duration()); + + group.start(); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim1->state(), QAnimationGroup::Running); + + QTest::qWait(50); + QVERIFY(group.currentTime() > 0); + + delete anim1; + QVERIFY(group.animationCount() == 0); + QCOMPARE(group.duration(), 0); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(group.currentTime(), 0); //that's the invariant +} + +void tst_QParallelAnimationGroup::startChildrenWithStoppedGroup() +{ + // test if children can be activated when their group is stopped + QParallelAnimationGroup group; + + TestAnimation anim1; + anim1.setStartValue(0); + anim1.setEndValue(100); + anim1.setDuration(200); + + TestAnimation anim2; + anim2.setStartValue(0); + anim2.setEndValue(100); + anim2.setDuration(200); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + + group.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + anim1.start(); + anim2.start(); + anim2.pause(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Paused); +} + +void tst_QParallelAnimationGroup::stopGroupWithRunningChild() +{ + // children that started independently will not be affected by a group stop + QParallelAnimationGroup group; + + TestAnimation anim1; + anim1.setStartValue(0); + anim1.setEndValue(100); + anim1.setDuration(200); + + TestAnimation anim2; + anim2.setStartValue(0); + anim2.setEndValue(100); + anim2.setDuration(200); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + + anim1.start(); + anim2.start(); + anim2.pause(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Paused); + + group.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Paused); + + anim1.stop(); + anim2.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); +} + +void tst_QParallelAnimationGroup::startGroupWithRunningChild() +{ + // as the group has precedence over its children, starting a group will restart all the children + QParallelAnimationGroup group; + + TestAnimation anim1; + anim1.setStartValue(0); + anim1.setEndValue(100); + anim1.setDuration(200); + + TestAnimation anim2; + anim2.setStartValue(0); + anim2.setEndValue(100); + anim2.setDuration(200); + + QSignalSpy stateChangedSpy1(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy stateChangedSpy2(&anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + QCOMPARE(stateChangedSpy1.count(), 0); + QCOMPARE(stateChangedSpy2.count(), 0); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + + anim1.start(); + anim2.start(); + anim2.pause(); + + QCOMPARE(qVariantValue(stateChangedSpy1.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(stateChangedSpy2.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(stateChangedSpy2.at(1).at(1)), + QAnimationGroup::Paused); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Paused); + + group.start(); + + QCOMPARE(stateChangedSpy1.count(), 3); + QCOMPARE(qVariantValue(stateChangedSpy1.at(1).at(1)), + QAnimationGroup::Stopped); + QCOMPARE(qVariantValue(stateChangedSpy1.at(2).at(1)), + QAnimationGroup::Running); + + QCOMPARE(stateChangedSpy2.count(), 4); + QCOMPARE(qVariantValue(stateChangedSpy2.at(2).at(1)), + QAnimationGroup::Stopped); + QCOMPARE(qVariantValue(stateChangedSpy2.at(3).at(1)), + QAnimationGroup::Running); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Running); +} + +void tst_QParallelAnimationGroup::zeroDurationAnimation() +{ + QParallelAnimationGroup group; + + TestAnimation anim1; + anim1.setStartValue(0); + anim1.setEndValue(100); + anim1.setDuration(0); + + TestAnimation anim2; + anim2.setStartValue(0); + anim2.setEndValue(100); + anim2.setDuration(100); + + QSignalSpy stateChangedSpy1(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy finishedSpy1(&anim1, SIGNAL(finished())); + + QSignalSpy stateChangedSpy2(&anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy finishedSpy2(&anim2, SIGNAL(finished())); + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + QCOMPARE(stateChangedSpy1.count(), 0); + group.start(); + QCOMPARE(stateChangedSpy1.count(), 2); + QCOMPARE(finishedSpy1.count(), 1); + QCOMPARE(qVariantValue(stateChangedSpy1.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(stateChangedSpy1.at(1).at(1)), + QAnimationGroup::Stopped); + + QCOMPARE(stateChangedSpy2.count(), 1); + QCOMPARE(finishedSpy2.count(), 0); + QCOMPARE(qVariantValue(stateChangedSpy1.at(0).at(1)), + QAnimationGroup::Running); + + + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Running); + QCOMPARE(group.state(), QAnimationGroup::Running); + + + group.stop(); + group.setLoopCount(4); + stateChangedSpy1.clear(); + stateChangedSpy2.clear(); + + group.start(); + QCOMPARE(stateChangedSpy1.count(), 2); + QCOMPARE(stateChangedSpy2.count(), 1); + group.setCurrentTime(50); + QCOMPARE(stateChangedSpy1.count(), 2); + QCOMPARE(stateChangedSpy2.count(), 1); + group.setCurrentTime(150); + QCOMPARE(stateChangedSpy1.count(), 4); + QCOMPARE(stateChangedSpy2.count(), 3); + group.setCurrentTime(50); + QCOMPARE(stateChangedSpy1.count(), 6); + QCOMPARE(stateChangedSpy2.count(), 5); + +} + +void tst_QParallelAnimationGroup::stopUncontrolledAnimations() +{ + QParallelAnimationGroup group; + + TestAnimation anim1; + anim1.setStartValue(0); + anim1.setEndValue(100); + anim1.setDuration(0); + + AnimationObject o1; + UncontrolledAnimation notTimeDriven(&o1, "value"); + QCOMPARE(notTimeDriven.totalDuration(), -1); + + TestAnimation loopsForever; + loopsForever.setStartValue(0); + loopsForever.setEndValue(100); + loopsForever.setDuration(100); + loopsForever.setLoopCount(-1); + + QSignalSpy stateChangedSpy(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + group.addAnimation(&anim1); + group.addAnimation(¬TimeDriven); + group.addAnimation(&loopsForever); + + group.start(); + + QCOMPARE(stateChangedSpy.count(), 2); + QCOMPARE(qVariantValue(stateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(stateChangedSpy.at(1).at(1)), + QAnimationGroup::Stopped); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running); + QCOMPARE(loopsForever.state(), QAnimationGroup::Running); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + + notTimeDriven.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); + QCOMPARE(loopsForever.state(), QAnimationGroup::Running); + + loopsForever.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); + QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped); +} + +struct AnimState { + AnimState(int time = -1) : time(time), state(-1) {} + AnimState(int time, int state) : time(time), state(state) {} + int time; + int state; +}; + +#define Running QAbstractAnimation::Running +#define Stopped QAbstractAnimation::Stopped + +Q_DECLARE_METATYPE(AnimState) +void tst_QParallelAnimationGroup::loopCount_data() +{ + QTest::addColumn("directionBackward"); + QTest::addColumn("setLoopCount"); + QTest::addColumn("initialGroupTime"); + QTest::addColumn("currentGroupTime"); + QTest::addColumn("expected1"); + QTest::addColumn("expected2"); + QTest::addColumn("expected3"); + + // D U R A T I O N + // 100 60*2 0 + // direction = Forward + QTest::newRow("50") << false << 3 << 0 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("100") << false << 3 << 0 << 100 << AnimState(100 ) << AnimState( 40, Running) << AnimState( 0, Stopped); + QTest::newRow("110") << false << 3 << 0 << 110 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("120") << false << 3 << 0 << 120 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped); + + QTest::newRow("170") << false << 3 << 0 << 170 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("220") << false << 3 << 0 << 220 << AnimState(100 ) << AnimState( 40, Running) << AnimState( 0, Stopped); + QTest::newRow("230") << false << 3 << 0 << 230 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("240") << false << 3 << 0 << 240 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped); + + QTest::newRow("290") << false << 3 << 0 << 290 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("340") << false << 3 << 0 << 340 << AnimState(100 ) << AnimState( 40, Running) << AnimState( 0, Stopped); + QTest::newRow("350") << false << 3 << 0 << 350 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("360") << false << 3 << 0 << 360 << AnimState(100, Stopped) << AnimState( 60 ) << AnimState( 0, Stopped); + + QTest::newRow("410") << false << 3 << 0 << 410 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped); + QTest::newRow("460") << false << 3 << 0 << 460 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped); + QTest::newRow("470") << false << 3 << 0 << 470 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped); + QTest::newRow("480") << false << 3 << 0 << 480 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped); + + // direction = Forward, rewind + QTest::newRow("120-110") << false << 3 << 120 << 110 << AnimState( 0, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("120-50") << false << 3 << 120 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("120-0") << false << 3 << 120 << 0 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped); + QTest::newRow("300-110") << false << 3 << 300 << 110 << AnimState( 0, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("300-50") << false << 3 << 300 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("300-0") << false << 3 << 300 << 0 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped); + QTest::newRow("115-105") << false << 3 << 115 << 105 << AnimState( 42, Stopped) << AnimState( 45, Running) << AnimState( 0, Stopped); + + // direction = Backward + QTest::newRow("b120-120") << true << 3 << 120 << 120 << AnimState( 42, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); + QTest::newRow("b120-110") << true << 3 << 120 << 110 << AnimState( 42, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("b120-100") << true << 3 << 120 << 100 << AnimState(100, Running) << AnimState( 40, Running) << AnimState( 0, Stopped); + QTest::newRow("b120-50") << true << 3 << 120 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("b120-0") << true << 3 << 120 << 0 << AnimState( 0, Stopped) << AnimState( 0, Stopped) << AnimState( 0, Stopped); + QTest::newRow("b360-170") << true << 3 << 360 << 170 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("b360-220") << true << 3 << 360 << 220 << AnimState(100, Running) << AnimState( 40, Running) << AnimState( 0, Stopped); + QTest::newRow("b360-210") << true << 3 << 360 << 210 << AnimState( 90, Running) << AnimState( 30, Running) << AnimState( 0, Stopped); + QTest::newRow("b360-120") << true << 3 << 360 << 120 << AnimState( 0, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); + + // rewind, direction = Backward + QTest::newRow("b50-110") << true << 3 << 50 << 110 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + QTest::newRow("b50-120") << true << 3 << 50 << 120 << AnimState(100, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); + QTest::newRow("b50-140") << true << 3 << 50 << 140 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped); + QTest::newRow("b50-240") << true << 3 << 50 << 240 << AnimState(100, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); + QTest::newRow("b50-260") << true << 3 << 50 << 260 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped); + QTest::newRow("b50-350") << true << 3 << 50 << 350 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + + // infinite looping + QTest::newRow("inf1220") << false << -1 << 0 << 1220 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped); + QTest::newRow("inf1310") << false << -1 << 0 << 1310 << AnimState( 100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + // infinite looping, direction = Backward (will only loop once) + QTest::newRow("b.inf120-120") << true << -1 << 120 << 120 << AnimState( 42, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); + QTest::newRow("b.inf120-20") << true << -1 << 120 << 20 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped); + QTest::newRow("b.inf120-110") << true << -1 << 120 << 110 << AnimState( 42, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); + + +} + +void tst_QParallelAnimationGroup::loopCount() +{ + QFETCH(bool, directionBackward); + QFETCH(int, setLoopCount); + QFETCH(int, initialGroupTime); + QFETCH(int, currentGroupTime); + QFETCH(AnimState, expected1); + QFETCH(AnimState, expected2); + QFETCH(AnimState, expected3); + + QParallelAnimationGroup group; + + TestAnimation anim1; + anim1.setStartValue(0); + anim1.setEndValue(100); + anim1.setDuration(100); + + TestAnimation anim2; + anim2.setStartValue(0); + anim2.setEndValue(100); + anim2.setDuration(60); //total 120 + anim2.setLoopCount(2); + + TestAnimation anim3; + anim3.setStartValue(0); + anim3.setEndValue(100); + anim3.setDuration(0); + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + group.addAnimation(&anim3); + + group.setLoopCount(setLoopCount); + if (initialGroupTime >= 0) + group.setCurrentTime(initialGroupTime); + if (directionBackward) + group.setDirection(QAbstractAnimation::Backward); + + group.start(); + if (initialGroupTime >= 0) + group.setCurrentTime(initialGroupTime); + + anim1.setCurrentTime(42); // 42 is "untouched" + anim2.setCurrentTime(42); + + group.setCurrentTime(currentGroupTime); + + QCOMPARE(anim1.currentTime(), expected1.time); + QCOMPARE(anim2.currentTime(), expected2.time); + QCOMPARE(anim3.currentTime(), expected3.time); + + if (expected1.state >=0) + QCOMPARE(int(anim1.state()), expected1.state); + if (expected2.state >=0) + QCOMPARE(int(anim2.state()), expected2.state); + if (expected3.state >=0) + QCOMPARE(int(anim3.state()), expected3.state); + +} + +void tst_QParallelAnimationGroup::autoAdd() +{ + QParallelAnimationGroup group; + QCOMPARE(group.duration(), 0); + TestAnimation2 *test = new TestAnimation2(250, &group); // 0, duration = 250; + QCOMPARE(test->group(), &group); + QCOMPARE(test->duration(), 250); + QCOMPARE(group.duration(), 250); + + test = new TestAnimation2(750, &group); // 1 + QCOMPARE(test->group(), &group); + QCOMPARE(group.duration(), 750); + test = new TestAnimation2(500, &group); // 2 + QCOMPARE(test->group(), &group); + QCOMPARE(group.duration(), 750); + + delete group.animationAt(1); // remove the one with duration = 750 + QCOMPARE(group.duration(), 500); + + delete group.animationAt(1); // remove the one with duration = 500 + QCOMPARE(group.duration(), 250); + + test = static_cast(group.animationAt(0)); + test->setParent(0); // remove the last one (with duration = 250) + QCOMPARE(test->group(), static_cast(0)); + QCOMPARE(group.duration(), 0); +} + +QTEST_MAIN(tst_QParallelAnimationGroup) +#include "tst_qparallelanimationgroup.moc" diff --git a/tests/auto/qpropertyanimation/qpropertyanimation.pro b/tests/auto/qpropertyanimation/qpropertyanimation.pro new file mode 100644 index 0000000..6d6ddbf --- /dev/null +++ b/tests/auto/qpropertyanimation/qpropertyanimation.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT = core gui +SOURCES += tst_qpropertyanimation.cpp + + diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp new file mode 100644 index 0000000..7e910d4 --- /dev/null +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -0,0 +1,919 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include + +//TESTED_CLASS=QPropertyAnimation +//TESTED_FILES= + +class UncontrolledAnimation : public QPropertyAnimation +{ + Q_OBJECT +public: + int duration() const { return -1; /* not time driven */ } + +protected: + void updateCurrentTime(int msecs) + { + QPropertyAnimation::updateCurrentTime(msecs); + if (msecs >= QPropertyAnimation::duration()) + stop(); + } +}; + +class tst_QPropertyAnimation : public QObject +{ + Q_OBJECT +public: + tst_QPropertyAnimation(); + virtual ~tst_QPropertyAnimation(); + +public Q_SLOTS: + void init(); + void cleanup(); + +private slots: + void construction(); + void setCurrentTime_data(); + void setCurrentTime(); + void statesAndSignals_data(); + void statesAndSignals(); + void deletion1(); + void deletion2(); + void deletion3(); + void duration0(); + void noStartValue(); + void noStartValueWithLoop(); + void startWhenAnotherIsRunning(); + void easingcurve_data(); + void easingcurve(); + void startWithoutStartValue(); + void playForwardBackward(); + void interpolated(); + void setStartEndValues(); + void zeroDurationStart(); + void operationsInStates_data(); + void operationsInStates(); + void oneKeyValue(); + void updateOnSetKeyValues(); +}; + +tst_QPropertyAnimation::tst_QPropertyAnimation() +{ +} + +tst_QPropertyAnimation::~tst_QPropertyAnimation() +{ +} + +void tst_QPropertyAnimation::init() +{ + qRegisterMetaType("QAbstractAnimation::State"); + qRegisterMetaType("QAbstractAnimation::DeletionPolicy"); +} + +void tst_QPropertyAnimation::cleanup() +{ +} + +class AnimationObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue) + Q_PROPERTY(qreal realValue READ realValue WRITE setRealValue) +public: + AnimationObject(int startValue = 0) + : v(startValue) + { } + + int value() const { return v; } + void setValue(int value) { v = value; } + + qreal realValue() const { return rv; } + void setRealValue(qreal value) { rv = value; } + + int v; + qreal rv; +}; + + +void tst_QPropertyAnimation::construction() +{ + QPropertyAnimation panimation; +} + +void tst_QPropertyAnimation::setCurrentTime_data() +{ + QTest::addColumn("duration"); + QTest::addColumn("loopCount"); + QTest::addColumn("currentTime"); + QTest::addColumn("testCurrentTime"); + QTest::addColumn("testCurrentLoop"); + + QTest::newRow("-1") << -1 << 1 << 0 << 0 << 0; + QTest::newRow("0") << 0 << 1 << 0 << 0 << 0; + QTest::newRow("1") << 0 << 1 << 1 << 0 << 0; + QTest::newRow("2") << 0 << 2 << 1 << 0 << 0; + QTest::newRow("3") << 1 << 1 << 0 << 0 << 0; + QTest::newRow("4") << 1 << 1 << 1 << 1 << 0; + QTest::newRow("5") << 1 << 2 << 1 << 0 << 1; + QTest::newRow("6") << 1 << 2 << 2 << 1 << 1; + QTest::newRow("7") << 1 << 2 << 3 << 1 << 1; + QTest::newRow("8") << 1 << 3 << 2 << 0 << 2; + QTest::newRow("9") << 1 << 3 << 3 << 1 << 2; + QTest::newRow("a") << 10 << 1 << 0 << 0 << 0; + QTest::newRow("b") << 10 << 1 << 1 << 1 << 0; + QTest::newRow("c") << 10 << 1 << 10 << 10 << 0; + QTest::newRow("d") << 10 << 2 << 10 << 0 << 1; + QTest::newRow("e") << 10 << 2 << 11 << 1 << 1; + QTest::newRow("f") << 10 << 2 << 20 << 10 << 1; + QTest::newRow("g") << 10 << 2 << 21 << 10 << 1; + QTest::newRow("negloop 0") << 10 << -1 << 0 << 0 << 0; + QTest::newRow("negloop 1") << 10 << -1 << 10 << 0 << 1; + QTest::newRow("negloop 2") << 10 << -1 << 15 << 5 << 1; + QTest::newRow("negloop 3") << 10 << -1 << 20 << 0 << 2; + QTest::newRow("negloop 4") << 10 << -1 << 30 << 0 << 3; +} + +void tst_QPropertyAnimation::setCurrentTime() +{ + QFETCH(int, duration); + QFETCH(int, loopCount); + QFETCH(int, currentTime); + QFETCH(int, testCurrentTime); + QFETCH(int, testCurrentLoop); + + QPropertyAnimation animation; + if (duration < 0) + QTest::ignoreMessage(QtWarningMsg, "QVariantAnimation::setDuration: cannot set a negative duration"); + animation.setDuration(duration); + animation.setLoopCount(loopCount); + animation.setCurrentTime(currentTime); + + QCOMPARE(animation.currentTime(), testCurrentTime); + QCOMPARE(animation.currentLoop(), testCurrentLoop); +} + +void tst_QPropertyAnimation::statesAndSignals_data() +{ + QTest::addColumn("uncontrolled"); + QTest::newRow("normal animation") << false; + QTest::newRow("animation with undefined duration") << true; +} + +void tst_QPropertyAnimation::statesAndSignals() +{ + QFETCH(bool, uncontrolled); + QPropertyAnimation *anim = uncontrolled ? new UncontrolledAnimation : new QPropertyAnimation; + anim->setDuration(100); + + QSignalSpy finishedSpy(anim, SIGNAL(finished())); + QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy currentLoopSpy(anim, SIGNAL(currentLoopChanged(int))); + + anim->setCurrentTime(1); + anim->setCurrentTime(100); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(runningSpy.count(), 0); + QCOMPARE(currentLoopSpy.count(), 0); + QCOMPARE(anim->state(), QAnimationGroup::Stopped); + + anim->setLoopCount(3); + anim->setCurrentTime(101); + + if (uncontrolled) + QSKIP("Uncontrolled animations don't handle looping", SkipSingle); + + QCOMPARE(currentLoopSpy.count(), 1); + QCOMPARE(anim->currentLoop(), 1); + + anim->setCurrentTime(0); + QCOMPARE(currentLoopSpy.count(), 2); + QCOMPARE(anim->currentLoop(), 0); + + anim->start(); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(runningSpy.count(), 1); //anim must have started + QCOMPARE(anim->currentLoop(), 0); + runningSpy.clear(); + + anim->stop(); + QCOMPARE(anim->state(), QAnimationGroup::Stopped); + QCOMPARE(runningSpy.count(), 1); //anim must have stopped + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(anim->currentTime(), 0); + QCOMPARE(anim->currentLoop(), 0); + QCOMPARE(currentLoopSpy.count(), 2); + runningSpy.clear(); + + anim->start(); + QTest::qWait(1000); + QCOMPARE(anim->state(), QAnimationGroup::Stopped); + QCOMPARE(runningSpy.count(), 2); //started and stopped again + runningSpy.clear(); + QCOMPARE(finishedSpy.count(), 1); + QCOMPARE(anim->currentTime(), 100); + QCOMPARE(anim->currentLoop(), 2); + QCOMPARE(currentLoopSpy.count(), 4); + + anim->start(); // auto-rewinds + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(anim->currentTime(), 0); + QCOMPARE(anim->currentLoop(), 0); + QCOMPARE(currentLoopSpy.count(), 5); + QCOMPARE(runningSpy.count(), 1); // anim has started + QCOMPARE(finishedSpy.count(), 1); + QCOMPARE(anim->currentLoop(), 0); + runningSpy.clear(); + + QTest::qWait(1000); + + QCOMPARE(currentLoopSpy.count(), 7); + QCOMPARE(anim->state(), QAnimationGroup::Stopped); + QCOMPARE(anim->currentLoop(), 2); + QCOMPARE(runningSpy.count(), 1); // anim has stopped + QCOMPARE(finishedSpy.count(), 2); + QCOMPARE(anim->currentTime(), 100); + + delete anim; +} + +void tst_QPropertyAnimation::deletion1() +{ + QObject *object = new QWidget; + QPointer anim = new QPropertyAnimation(object,"minimumWidth"); + + //test that the animation is deleted correctly depending of the deletion flag passed in start() + QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy finishedSpy(anim, SIGNAL(finished())); + anim->setStartValue(10); + anim->setEndValue(20); + anim->setDuration(200); + anim->start(); + QCOMPARE(runningSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + + QVERIFY(anim); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QTest::qWait(100); + QVERIFY(anim); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QTest::qWait(150); + QVERIFY(anim); //The animation should not have been deleted + QCOMPARE(anim->state(), QAnimationGroup::Stopped); + QCOMPARE(runningSpy.count(), 2); + QCOMPARE(finishedSpy.count(), 1); + + anim->start(QVariantAnimation::DeleteWhenStopped); + QVERIFY(anim); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QTest::qWait(100); + QVERIFY(anim); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QTest::qWait(150); + QVERIFY(!anim); //The animation must have been deleted + QCOMPARE(runningSpy.count(), 4); + QCOMPARE(finishedSpy.count(), 2); + delete object; +} + +void tst_QPropertyAnimation::deletion2() +{ + //test that the animation get deleted if the object is deleted + QObject *object = new QWidget; + QPointer anim = new QPropertyAnimation(object,"minimumWidth"); + anim->setStartValue(10); + anim->setEndValue(20); + anim->setDuration(200); + + QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy finishedSpy(anim, SIGNAL(finished())); + + anim->setStartValue(10); + anim->setEndValue(20); + anim->setDuration(200); + anim->start(); + + QTest::qWait(50); + QVERIFY(anim); + QCOMPARE(anim->state(), QAnimationGroup::Running); + + QCOMPARE(runningSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + + //we can't call deletaLater directly because the delete would only happen in the next loop of _this_ event loop + QTimer::singleShot(0, object, SLOT(deleteLater())); + QTest::qWait(50); + + QVERIFY(anim->targetObject() == 0); +} + +void tst_QPropertyAnimation::deletion3() +{ + //test that the stopped signal is emit when the animation is destroyed + QObject *object = new QWidget; + QPropertyAnimation *anim = new QPropertyAnimation(object,"minimumWidth"); + anim->setStartValue(10); + anim->setEndValue(20); + anim->setDuration(200); + + QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy finishedSpy(anim, SIGNAL(finished())); + anim->start(); + + QTest::qWait(50); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(runningSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + delete anim; + QCOMPARE(runningSpy.count(), 2); + QCOMPARE(finishedSpy.count(), 0); +} + +void tst_QPropertyAnimation::duration0() +{ + QObject o; + o.setProperty("ole", 42); + QCOMPARE(o.property("ole").toInt(), 42); + + QPropertyAnimation animation(&o, "ole"); + animation.setEndValue(43); + QVERIFY(!animation.currentValue().isValid()); + QCOMPARE(animation.currentValue().toInt(), 0); + QCOMPARE(o.property("ole").toInt(), 42); + animation.setDuration(0); + animation.start(); + QCOMPARE(animation.state(), QAnimationGroup::Stopped); + QCOMPARE(animation.currentTime(), 0); + QCOMPARE(o.property("ole").toInt(), 43); +} + +class StartValueTester : public QObject +{ + Q_OBJECT + Q_PROPERTY(int ole READ ole WRITE setOle) +public: + StartValueTester() : o(0) { } + int ole() const { return o; } + void setOle(int v) { o = v; values << v; } + + int o; + QList values; +}; + +void tst_QPropertyAnimation::noStartValue() +{ + StartValueTester o; + o.setProperty("ole", 42); + o.values.clear(); + + QPropertyAnimation a(&o, "ole"); + a.setEndValue(420); + a.setDuration(250); + a.start(); + + QTest::qWait(300); + + QCOMPARE(o.values.first(), 42); + QCOMPARE(o.values.last(), 420); +} + +void tst_QPropertyAnimation::noStartValueWithLoop() +{ + StartValueTester o; + o.setProperty("ole", 42); + o.values.clear(); + + QPropertyAnimation a(&o, "ole"); + a.setEndValue(420); + a.setDuration(250); + a.setLoopCount(2); + a.start(); + + a.setCurrentTime(250); + QCOMPARE(o.values.first(), 42); + QCOMPARE(a.currentValue().toInt(), 42); + QCOMPARE(o.values.last(), 42); + + a.setCurrentTime(500); + QCOMPARE(a.currentValue().toInt(), 420); +} + +void tst_QPropertyAnimation::startWhenAnotherIsRunning() +{ + StartValueTester o; + o.setProperty("ole", 42); + o.values.clear(); + + { + //normal case: the animation finishes and is deleted + QPointer anim = new QPropertyAnimation(&o, "ole"); + QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + anim->start(QVariantAnimation::DeleteWhenStopped); + QTest::qWait(anim->duration() + 50); + QCOMPARE(runningSpy.count(), 2); //started and then stopped + QVERIFY(!anim); + } + + { + QPointer anim = new QPropertyAnimation(&o, "ole"); + QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + anim->start(QVariantAnimation::DeleteWhenStopped); + QTest::qWait(anim->duration()/2); + QPointer anim2 = new QPropertyAnimation(&o, "ole"); + QCOMPARE(runningSpy.count(), 1); + QCOMPARE(anim->state(), QVariantAnimation::Running); + + //anim2 will interrupt anim1 + QMetaObject::invokeMethod(anim2, "start", Qt::QueuedConnection, Q_ARG(QAbstractAnimation::DeletionPolicy, QVariantAnimation::DeleteWhenStopped)); + QTest::qWait(50); + QVERIFY(!anim); //anim should have been deleted + QVERIFY(anim2); + QTest::qWait(anim2->duration()); + QVERIFY(!anim2); //anim2 is finished: it should have been deleted by now + QVERIFY(!anim); + } + +} + +// copy from easing.cpp in case that function changes definition +static qreal easeInOutBack(qreal t) +{ + qreal s = 1.70158; + qreal t_adj = 2.0f * (qreal)t; + if (t_adj < 1) { + s *= 1.525f; + return 1.0/2*(t_adj*t_adj*((s+1)*t_adj - s)); + } else { + t_adj -= 2; + s *= 1.525f; + return 1.0/2*(t_adj*t_adj*((s+1)*t_adj + s) + 2); + } +} + +void tst_QPropertyAnimation::easingcurve_data() +{ + QTest::addColumn("currentTime"); + QTest::addColumn("expectedvalue"); + + QTest::newRow("interpolation1") << 0 << 0; + QTest::newRow("interpolation2") << 1000 << 1000; + QTest::newRow("extrapolationbelow") << 250 << -99; + QTest::newRow("extrapolationabove") << 750 << 1099; +} + +void tst_QPropertyAnimation::easingcurve() +{ + QFETCH(int, currentTime); + QFETCH(int, expectedvalue); + QObject o; + o.setProperty("ole", 42); + QCOMPARE(o.property("ole").toInt(), 42); + + QPropertyAnimation pAnimation(&o, "ole"); + pAnimation.setStartValue(0); + pAnimation.setEndValue(1000); + pAnimation.setDuration(1000); + + // this easingcurve assumes that we extrapolate before startValue and after endValue + QEasingCurve easingCurve; + easingCurve.setCustomType(easeInOutBack); + pAnimation.setEasingCurve(easingCurve); + pAnimation.start(); + pAnimation.pause(); + pAnimation.setCurrentTime(currentTime); + QCOMPARE(o.property("ole").toInt(), expectedvalue); +} + +void tst_QPropertyAnimation::startWithoutStartValue() +{ + QObject o; + o.setProperty("ole", 42); + QCOMPARE(o.property("ole").toInt(), 42); + + QPropertyAnimation anim(&o, "ole"); + anim.setEndValue(100); + + anim.start(); + + QTest::qWait(100); + int current = anim.currentValue().toInt(); + //it is somewhere in the animation + QVERIFY(current > 42); + QVERIFY(current < 100); + + QTest::qWait(200); + QCOMPARE(anim.state(), QVariantAnimation::Stopped); + + anim.setEndValue(110); + anim.start(); + current = anim.currentValue().toInt(); + // the default start value will reevaluate the current property + // and set it to the end value of the last iteration + QCOMPARE(current, 100); + QTest::qWait(100); + current = anim.currentValue().toInt(); + //it is somewhere in the animation + QVERIFY(current >= 100); + QVERIFY(current <= 110); +} + +void tst_QPropertyAnimation::playForwardBackward() +{ + QObject o; + o.setProperty("ole", 0); + QCOMPARE(o.property("ole").toInt(), 0); + + QPropertyAnimation anim(&o, "ole"); + anim.setEndValue(100); + anim.start(); + QTest::qWait(anim.duration() + 50); + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); + QCOMPARE(anim.currentTime(), anim.duration()); + + //the animation is at the end + anim.setDirection(QVariantAnimation::Backward); + anim.start(); + QCOMPARE(anim.state(), QAbstractAnimation::Running); + QTest::qWait(anim.duration() + 50); + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); + QCOMPARE(anim.currentTime(), 0); + + //the direction is backward + //restarting should jump to the end + anim.start(); + QCOMPARE(anim.state(), QAbstractAnimation::Running); + QCOMPARE(anim.currentTime(), anim.duration()); + QTest::qWait(anim.duration() + 50); + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); + QCOMPARE(anim.currentTime(), 0); +} + +struct Number +{ + Number() {} + Number(int n) + : n(n) {} + + Number(const Number &other) + : n(other.n){} + + Number &operator=(const Number &other) { + n = other.n; + return *this; + } + bool operator==(const Number &other) const { + return n == other.n; + } + + int n; +}; + +Q_DECLARE_METATYPE(Number) +Q_DECLARE_METATYPE(QAbstractAnimation::State) + +QVariant numberInterpolator(const Number &f, const Number &t, qreal progress) +{ + return qVariantFromValue(Number(f.n + (t.n - f.n)*progress)); +} + +QVariant xaxisQPointInterpolator(const QPointF &f, const QPointF &t, qreal progress) +{ + return QPointF(f.x() + (t.x() - f.x())*progress, f.y()); +} + +void tst_QPropertyAnimation::interpolated() +{ + QObject o; + o.setProperty("point", QPointF()); //this will avoid warnings + o.setProperty("number", qVariantFromValue(Number(42))); + QCOMPARE(qVariantValue(o.property("number")), Number(42)); + { + qRegisterAnimationInterpolator(numberInterpolator); + QPropertyAnimation anim(&o, "number"); + anim.setStartValue(qVariantFromValue(Number(0))); + anim.setEndValue(qVariantFromValue(Number(100))); + anim.setDuration(1000); + anim.start(); + anim.pause(); + anim.setCurrentTime(100); + Number t(qVariantValue(o.property("number"))); + QCOMPARE(t, Number(10)); + anim.setCurrentTime(500); + QCOMPARE(qVariantValue(o.property("number")), Number(50)); + } + { + qRegisterAnimationInterpolator(xaxisQPointInterpolator); + QPropertyAnimation anim(&o, "point"); + anim.setStartValue(QPointF(0,0)); + anim.setEndValue(QPointF(100, 100)); + anim.setDuration(1000); + anim.start(); + anim.pause(); + anim.setCurrentTime(100); + QCOMPARE(o.property("point"), QVariant(QPointF(10, 0))); + anim.setCurrentTime(500); + QCOMPARE(o.property("point"), QVariant(QPointF(50, 0))); + } + { + // unregister it and see if we get back the default behaviour + qRegisterAnimationInterpolator(0); + QPropertyAnimation anim(&o, "point"); + anim.setStartValue(QPointF(0,0)); + anim.setEndValue(QPointF(100, 100)); + anim.setDuration(1000); + anim.start(); + anim.pause(); + anim.setCurrentTime(100); + QCOMPARE(o.property("point").toPointF(), QPointF(10, 10)); + anim.setCurrentTime(500); + QCOMPARE(o.property("point").toPointF(), QPointF(50, 50)); + } + + { + // Interpolate a qreal property with a int interpolator + AnimationObject o1; + o1.setRealValue(42.42); + QPropertyAnimation anim(&o1, "realValue"); + anim.setStartValue(0); + anim.setEndValue(100); + anim.start(); + QCOMPARE(o1.realValue(), qreal(0)); + anim.setCurrentTime(250); + QCOMPARE(o1.realValue(), qreal(100)); + } +} + +void tst_QPropertyAnimation::setStartEndValues() +{ + //this tests the start value, end value and default start value + QObject o; + o.setProperty("ole", 42); + QPropertyAnimation anim(&o, "ole"); + QVariantAnimation::KeyValues values; + QCOMPARE(anim.keyValues(), values); + + //let's add a start value + anim.setStartValue(0); + values << QVariantAnimation::KeyValue(0, 0); + QCOMPARE(anim.keyValues(), values); + + anim.setEndValue(10); + values << QVariantAnimation::KeyValue(1, 10); + QCOMPARE(anim.keyValues(), values); + + //now we can play with objects + QCOMPARE(o.property("ole").toInt(), 42); + QCOMPARE(o.property("ole").toInt(), 42); + anim.start(); + QVERIFY(anim.startValue().isValid()); + QCOMPARE(o.property("ole"), anim.startValue()); + + //now we remove the explicit start value and test the implicit one + anim.stop(); + o.setProperty("ole", 42); + values.remove(0); + anim.setStartValue(QVariant()); //reset the start value + QCOMPARE(anim.keyValues(), values); + QVERIFY(!anim.startValue().isValid()); + anim.start(); + QCOMPARE(o.property("ole").toInt(), 42); + anim.setCurrentTime(anim.duration()/2); + QCOMPARE(o.property("ole").toInt(), 26); //just in the middle of the animation + anim.setCurrentTime(anim.duration()); + QCOMPARE(anim.state(), QAnimationGroup::Stopped); //it should have stopped + QVERIFY(anim.endValue().isValid()); + QCOMPARE(o.property("ole"), anim.endValue()); //end of the animations + + //now we set back the startValue + anim.setStartValue(5); + QVERIFY(anim.startValue().isValid()); + anim.start(); + QCOMPARE(o.property("ole").toInt(), 5); +} + +void tst_QPropertyAnimation::zeroDurationStart() +{ + QPropertyAnimation anim; + QSignalSpy spy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + anim.setDuration(0); + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); + anim.start(); + //the animation stops immediately + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); + QCOMPARE(spy.count(), 2); + + //let's check the first state change + const QVariantList firstChange = spy.first(); + //old state + QCOMPARE(qVariantValue(firstChange.first()), QAbstractAnimation::Stopped); + //new state + QCOMPARE(qVariantValue(firstChange.last()), QAbstractAnimation::Running); + + //let's check the first state change + const QVariantList secondChange = spy.last(); + //old state + QCOMPARE(qVariantValue(secondChange.first()), QAbstractAnimation::Running); + //new state + QCOMPARE(qVariantValue(secondChange.last()), QAbstractAnimation::Stopped); +} + +#define Pause 1 +#define Start 2 +#define Resume 3 +#define Stop 4 + +void tst_QPropertyAnimation::operationsInStates_data() +{ + QTest::addColumn("originState"); + QTest::addColumn("operation"); + QTest::addColumn("expectedWarning"); + QTest::addColumn("expectedState"); + + QString pauseWarn(QLatin1String("QAbstractAnimation::pause: Cannot pause a stopped animation")); + QString resumeWarn(QLatin1String("QAbstractAnimation::resume: Cannot resume an animation that is not paused")); + + QTest::newRow("S-pause") << QAbstractAnimation::Stopped << Pause << pauseWarn << QAbstractAnimation::Stopped; + QTest::newRow("S-start") << QAbstractAnimation::Stopped << Start << QString() << QAbstractAnimation::Running; + QTest::newRow("S-resume") << QAbstractAnimation::Stopped << Resume << resumeWarn << QAbstractAnimation::Stopped; + QTest::newRow("S-stop") << QAbstractAnimation::Stopped << Stop << QString() << QAbstractAnimation::Stopped; + + QTest::newRow("P-pause") << QAbstractAnimation::Paused << Pause << QString() << QAbstractAnimation::Paused; + QTest::newRow("P-start") << QAbstractAnimation::Paused << Start << QString() << QAbstractAnimation::Running; + QTest::newRow("P-resume") << QAbstractAnimation::Paused << Resume << QString() << QAbstractAnimation::Running; + QTest::newRow("P-stop") << QAbstractAnimation::Paused << Stop << QString() << QAbstractAnimation::Stopped; + + QTest::newRow("R-pause") << QAbstractAnimation::Running << Pause << QString() << QAbstractAnimation::Paused; + QTest::newRow("R-start") << QAbstractAnimation::Running << Start << QString() << QAbstractAnimation::Running; + QTest::newRow("R-resume") << QAbstractAnimation::Running << Resume << resumeWarn << QAbstractAnimation::Running; + QTest::newRow("R-stop") << QAbstractAnimation::Running << Stop << QString() << QAbstractAnimation::Stopped; +} + +void tst_QPropertyAnimation::operationsInStates() +{ +/** + * | pause() |start() |resume() |stop() + * ----------+------------+-----------+-----------+-------------------+ + * Stopped | Stopped |Running |Stopped |Stopped | + * _| qWarning |restart |qWarning | | + * Paused | Paused |Running |Running |Stopped | + * _| | | | | + * Running | Paused |Running |Running |Stopped | + * | |restart |qWarning | | + * ----------+------------+-----------+-----------+-------------------+ +**/ + + QFETCH(QAbstractAnimation::State, originState); + QFETCH(int, operation); + QFETCH(QString, expectedWarning); + QFETCH(QAbstractAnimation::State, expectedState); + + QObject o; + o.setProperty("ole", 42); + QPropertyAnimation anim(&o, "ole"); + QSignalSpy spy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + anim.stop(); + switch (originState) { + case QAbstractAnimation::Stopped: + break; + case QAbstractAnimation::Paused: + anim.start(); + anim.pause(); + break; + case QAbstractAnimation::Running: + anim.start(); + break; + } + if (!expectedWarning.isEmpty()) { + QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); + } + QCOMPARE(anim.state(), originState); + switch (operation) { + case Pause: + anim.pause(); + break; + case Start: + anim.start(); + break; + case Resume: + anim.resume(); + break; + case Stop: + anim.stop(); + break; + } + + QCOMPARE(anim.state(), expectedState); +} +#undef Pause +#undef Start +#undef Resume +#undef Stop + +void tst_QPropertyAnimation::oneKeyValue() +{ + QObject o; + o.setProperty("ole", 42); + QCOMPARE(o.property("ole").toInt(), 42); + + QPropertyAnimation animation(&o, "ole"); + animation.setStartValue(43); + animation.setEndValue(44); + animation.setDuration(100); + + animation.setCurrentTime(0); + + QVERIFY(animation.currentValue().isValid()); + QCOMPARE(animation.currentValue().toInt(), 43); + QCOMPARE(o.property("ole").toInt(), 42); + + // remove the last key value + animation.setKeyValueAt(1.0, QVariant()); + + // we will neither interpolate, nor update the current value + // since there is only one 1 key value defined + animation.setCurrentTime(100); + + // the animation should not have been modified + QVERIFY(animation.currentValue().isValid()); + QCOMPARE(animation.currentValue().toInt(), 43); + QCOMPARE(o.property("ole").toInt(), 42); +} + +void tst_QPropertyAnimation::updateOnSetKeyValues() +{ + QObject o; + o.setProperty("ole", 100); + QCOMPARE(o.property("ole").toInt(), 100); + + QPropertyAnimation animation(&o, "ole"); + animation.setStartValue(100); + animation.setEndValue(200); + animation.setDuration(100); + + animation.setCurrentTime(50); + QCOMPARE(animation.currentValue().toInt(), 150); + animation.setKeyValueAt(0.0, 300); + QCOMPARE(animation.currentValue().toInt(), 250); + + o.setProperty("ole", 100); + QPropertyAnimation animation2(&o, "ole"); + QVariantAnimation::KeyValues kValues; + kValues << QVariantAnimation::KeyValue(0.0, 100) << QVariantAnimation::KeyValue(1.0, 200); + animation2.setKeyValues(kValues); + animation2.setDuration(100); + animation2.setCurrentTime(50); + QCOMPARE(animation2.currentValue().toInt(), 150); + + kValues.clear(); + kValues << QVariantAnimation::KeyValue(0.0, 300) << QVariantAnimation::KeyValue(1.0, 200); + animation2.setKeyValues(kValues); + + QCOMPARE(animation2.currentValue().toInt(), animation.currentValue().toInt()); +} + +QTEST_MAIN(tst_QPropertyAnimation) +#include "tst_qpropertyanimation.moc" diff --git a/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro b/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro new file mode 100644 index 0000000..ad861c3 --- /dev/null +++ b/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT = core gui +SOURCES += tst_qsequentialanimationgroup.cpp + + diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp new file mode 100644 index 0000000..0631343 --- /dev/null +++ b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp @@ -0,0 +1,1649 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "../../shared/util.h" + +#include +#include + +//TESTED_CLASS=QSequentialAnimationGroup +//TESTED_FILES= + +Q_DECLARE_METATYPE(QAbstractAnimation::State) +Q_DECLARE_METATYPE(QAbstractAnimation*) + +class tst_QSequentialAnimationGroup : public QObject +{ + Q_OBJECT +public: + tst_QSequentialAnimationGroup(); + virtual ~tst_QSequentialAnimationGroup(); + +public Q_SLOTS: + void init(); + void cleanup(); + +private slots: + void construction(); + void setCurrentTime(); + void setCurrentTimeWithUncontrolledAnimation(); + void seekingForwards(); + void seekingBackwards(); + void pauseAndResume(); + void restart(); + void looping(); + void startDelay(); + void clearGroup(); + void groupWithZeroDurationAnimations(); + void propagateGroupUpdateToChildren(); + void updateChildrenWithRunningGroup(); + void deleteChildrenWithRunningGroup(); + void startChildrenWithStoppedGroup(); + void stopGroupWithRunningChild(); + void startGroupWithRunningChild(); + void zeroDurationAnimation(); + void stopUncontrolledAnimations(); + void finishWithUncontrolledAnimation(); + void addRemoveAnimation(); + void currentAnimation(); + void currentAnimationWithZeroDuration(); + void insertAnimation(); + void clearAnimations(); +}; + +tst_QSequentialAnimationGroup::tst_QSequentialAnimationGroup() +{ +} + +tst_QSequentialAnimationGroup::~tst_QSequentialAnimationGroup() +{ +} + +void tst_QSequentialAnimationGroup::init() +{ + qRegisterMetaType("QAbstractAnimation::State"); + qRegisterMetaType("QAbstractAnimation*"); +} + +void tst_QSequentialAnimationGroup::cleanup() +{ +} + +void tst_QSequentialAnimationGroup::construction() +{ + QSequentialAnimationGroup animationgroup; +} + +class AnimationObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue) +public: + AnimationObject(int startValue = 0) + : v(startValue) + { } + + int value() const { return v; } + void setValue(int value) { v = value; } + + int v; +}; + +class TestAnimation : public QVariantAnimation +{ + Q_OBJECT +public: + virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)}; + virtual void updateState(QAbstractAnimation::State oldState, + QAbstractAnimation::State newState) + { + Q_UNUSED(oldState) + Q_UNUSED(newState) + }; +}; + +class UncontrolledAnimation : public QPropertyAnimation +{ + Q_OBJECT +public: + UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0) + : QPropertyAnimation(target, propertyName, parent) + { + setDuration(250); + } + + int duration() const { return -1; /* not time driven */ } + +protected: + void updateCurrentTime(int msecs) + { + QPropertyAnimation::updateCurrentTime(msecs); + if (msecs >= QPropertyAnimation::duration()) + stop(); + } +}; + +void tst_QSequentialAnimationGroup::setCurrentTime() +{ + AnimationObject s_o1; + AnimationObject s_o2; + AnimationObject s_o3; + + // sequence operating on same object/property + QAnimationGroup *sequence = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); + a2_s_o1->setLoopCount(3); + sequence->addAnimation(a1_s_o1); + sequence->addAnimation(a2_s_o1); + sequence->addAnimation(a3_s_o1); + + // sequence operating on different object/properties + QAnimationGroup *sequence2 = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); + QVariantAnimation *a1_s_o3 = new QPropertyAnimation(&s_o3, "value"); + sequence2->addAnimation(a1_s_o2); + sequence2->addAnimation(a1_s_o3); + + QSequentialAnimationGroup group; + group.addAnimation(sequence); + group.addAnimation(sequence2); + + // Current time = 1 + group.setCurrentTime(1); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(sequence->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + + QCOMPARE(group.currentTime(), 1); + QCOMPARE(sequence->currentTime(), 1); + QCOMPARE(a1_s_o1->currentTime(), 1); + QCOMPARE(a2_s_o1->currentTime(), 0); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // Current time = 250 + group.setCurrentTime(250); + QCOMPARE(group.currentTime(), 250); + QCOMPARE(sequence->currentTime(), 250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 0); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // Current time = 251 + group.setCurrentTime(251); + QCOMPARE(group.currentTime(), 251); + QCOMPARE(sequence->currentTime(), 251); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 1); + QCOMPARE(a2_s_o1->currentLoop(), 0); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(sequence2->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // Current time = 750 + group.setCurrentTime(750); + QCOMPARE(group.currentTime(), 750); + QCOMPARE(sequence->currentTime(), 750); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 0); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(sequence2->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // Current time = 1000 + group.setCurrentTime(1000); + QCOMPARE(group.currentTime(), 1000); + QCOMPARE(sequence->currentTime(), 1000); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(sequence2->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // Current time = 1010 + group.setCurrentTime(1010); + QCOMPARE(group.currentTime(), 1010); + QCOMPARE(sequence->currentTime(), 1010); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 10); + QCOMPARE(sequence2->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // Current time = 1250 + group.setCurrentTime(1250); + QCOMPARE(group.currentTime(), 1250); + QCOMPARE(sequence->currentTime(), 1250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 250); + QCOMPARE(sequence2->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // Current time = 1500 + group.setCurrentTime(1500); + QCOMPARE(group.currentTime(), 1500); + QCOMPARE(sequence->currentTime(), 1250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 250); + QCOMPARE(sequence2->currentTime(), 250); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // Current time = 1750 + group.setCurrentTime(1750); + QCOMPARE(group.currentTime(), 1750); + QCOMPARE(sequence->currentTime(), 1250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 250); + QCOMPARE(sequence2->currentTime(), 500); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(a1_s_o3->currentTime(), 250); + + // Current time = 2000 + group.setCurrentTime(2000); + QCOMPARE(group.currentTime(), 1750); + QCOMPARE(sequence->currentTime(), 1250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 250); + QCOMPARE(sequence2->currentTime(), 500); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(a1_s_o3->currentTime(), 250); +} + +void tst_QSequentialAnimationGroup::setCurrentTimeWithUncontrolledAnimation() +{ + AnimationObject s_o1; + AnimationObject s_o2; + AnimationObject t_o1; + AnimationObject t_o2; + + // sequence operating on different object/properties + QAnimationGroup *sequence = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); + sequence->addAnimation(a1_s_o1); + sequence->addAnimation(a1_s_o2); + + UncontrolledAnimation *notTimeDriven = new UncontrolledAnimation(&t_o1, "value"); + QCOMPARE(notTimeDriven->totalDuration(), -1); + + QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value"); + loopsForever->setLoopCount(-1); + QCOMPARE(loopsForever->totalDuration(), -1); + + QSequentialAnimationGroup group; + group.addAnimation(sequence); + group.addAnimation(notTimeDriven); + group.addAnimation(loopsForever); + group.start(); + group.pause(); // this allows the group to listen for the finish signal of its children + + // Current time = 1 + group.setCurrentTime(1); + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(sequence->state(), QAnimationGroup::Paused); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); + QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); + + QCOMPARE(group.currentTime(), 1); + QCOMPARE(sequence->currentTime(), 1); + QCOMPARE(a1_s_o1->currentTime(), 1); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(notTimeDriven->currentTime(), 0); + QCOMPARE(loopsForever->currentTime(), 0); + + // Current time = 250 + group.setCurrentTime(250); + QCOMPARE(group.currentTime(), 250); + QCOMPARE(sequence->currentTime(), 250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(notTimeDriven->currentTime(), 0); + QCOMPARE(loopsForever->currentTime(), 0); + + // Current time = 500 + group.setCurrentTime(500); + QCOMPARE(group.currentTime(), 500); + QCOMPARE(sequence->currentTime(), 500); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(notTimeDriven->currentTime(), 0); + QCOMPARE(loopsForever->currentTime(), 0); + QCOMPARE(group.currentAnimation(), notTimeDriven); + + // Current time = 505 + group.setCurrentTime(505); + QCOMPARE(group.currentTime(), 505); + QCOMPARE(sequence->currentTime(), 500); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(notTimeDriven->currentTime(), 5); + QCOMPARE(loopsForever->currentTime(), 0); + QCOMPARE(group.currentAnimation(), notTimeDriven); + QCOMPARE(sequence->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(notTimeDriven->state(), QAnimationGroup::Paused); + QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); + + // Current time = 750 (end of notTimeDriven animation) + group.setCurrentTime(750); + QCOMPARE(group.currentTime(), 750); + QCOMPARE(sequence->currentTime(), 500); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(notTimeDriven->currentTime(), 250); + QCOMPARE(loopsForever->currentTime(), 0); + QCOMPARE(group.currentAnimation(), loopsForever); + QCOMPARE(sequence->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); + QCOMPARE(loopsForever->state(), QAnimationGroup::Paused); + + // Current time = 800 (as notTimeDriven was finished at 750, loopsforever should still run) + group.setCurrentTime(800); + QCOMPARE(group.currentTime(), 800); + QCOMPARE(group.currentAnimation(), loopsForever); + QCOMPARE(sequence->currentTime(), 500); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(notTimeDriven->currentTime(), 250); + QCOMPARE(loopsForever->currentTime(), 50); + + loopsForever->stop(); // this should stop the group + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(sequence->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); + QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); +} + +void tst_QSequentialAnimationGroup::seekingForwards() +{ + AnimationObject s_o1; + AnimationObject s_o2; + AnimationObject s_o3; + + // sequence operating on same object/property + QAnimationGroup *sequence = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); + a2_s_o1->setLoopCount(3); + sequence->addAnimation(a1_s_o1); + sequence->addAnimation(a2_s_o1); + sequence->addAnimation(a3_s_o1); + + // sequence operating on different object/properties + QAnimationGroup *sequence2 = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); + QVariantAnimation *a1_s_o3 = new QPropertyAnimation(&s_o3, "value"); + sequence2->addAnimation(a1_s_o2); + sequence2->addAnimation(a1_s_o3); + + QSequentialAnimationGroup group; + group.addAnimation(sequence); + group.addAnimation(sequence2); + + // Current time = 1 + group.setCurrentTime(1); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(sequence->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped); + + QCOMPARE(group.currentTime(), 1); + QCOMPARE(sequence->currentTime(), 1); + QCOMPARE(a1_s_o1->currentTime(), 1); + QCOMPARE(a2_s_o1->currentTime(), 0); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(sequence2->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // Current time = 1500 + group.setCurrentTime(1500); + QCOMPARE(group.currentTime(), 1500); + QCOMPARE(sequence->currentTime(), 1250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 250); + QCOMPARE(sequence2->currentTime(), 250); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(a1_s_o3->currentTime(), 0); + + // this will restart the group + group.start(); + group.pause(); + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(sequence->state(), QAnimationGroup::Paused); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused); + QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped); + + // Current time = 1750 + group.setCurrentTime(1750); + QCOMPARE(group.currentTime(), 1750); + QCOMPARE(sequence->currentTime(), 1250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 250); + QCOMPARE(sequence2->currentTime(), 500); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(a1_s_o3->currentTime(), 250); +} + +void tst_QSequentialAnimationGroup::seekingBackwards() +{ + AnimationObject s_o1; + AnimationObject s_o2; + AnimationObject s_o3; + + // sequence operating on same object/property + QAnimationGroup *sequence = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); + a2_s_o1->setLoopCount(3); + sequence->addAnimation(a1_s_o1); + sequence->addAnimation(a2_s_o1); + sequence->addAnimation(a3_s_o1); + + // sequence operating on different object/properties + QAnimationGroup *sequence2 = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); + QVariantAnimation *a1_s_o3 = new QPropertyAnimation(&s_o3, "value"); + sequence2->addAnimation(a1_s_o2); + sequence2->addAnimation(a1_s_o3); + + QSequentialAnimationGroup group; + group.addAnimation(sequence); + group.addAnimation(sequence2); + + group.start(); + + // Current time = 1600 + group.setCurrentTime(1600); + QCOMPARE(group.currentTime(), 1600); + QCOMPARE(sequence->currentTime(), 1250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 250); + QCOMPARE(sequence2->currentTime(), 350); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(a1_s_o3->currentTime(), 100); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(sequence->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(sequence2->state(), QAnimationGroup::Running); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o3->state(), QAnimationGroup::Running); + + // Seeking backwards, current time = 1 + group.setCurrentTime(1); + QCOMPARE(group.currentTime(), 1); + QCOMPARE(sequence->currentTime(), 1); + QCOMPARE(a1_s_o1->currentTime(), 1); + + QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children," + "hence they don't reset from their current animation", Continue); + QCOMPARE(a2_s_o1->currentTime(), 0); + QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children," + "hence they don't reset from their current animation", Continue); + QCOMPARE(a2_s_o1->currentLoop(), 0); + QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children," + "hence they don't reset from their current animation", Continue); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(sequence2->currentTime(), 0); + QCOMPARE(a1_s_o2->currentTime(), 0); + QCOMPARE(a1_s_o3->currentTime(), 0); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(sequence->state(), QAnimationGroup::Running); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Running); + QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped); + + // Current time = 2000 + group.setCurrentTime(2000); + QCOMPARE(group.currentTime(), 1750); + QCOMPARE(sequence->currentTime(), 1250); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 2); + QCOMPARE(a3_s_o1->currentTime(), 250); + QCOMPARE(sequence2->currentTime(), 500); + QCOMPARE(a1_s_o2->currentTime(), 250); + QCOMPARE(a1_s_o3->currentTime(), 250); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(sequence->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); + QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped); +} + +typedef QList StateList; + +static bool compareStates(const QSignalSpy& spy, const StateList &expectedStates) +{ + bool equals = true; + for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) { + if (i >= spy.count() || i >= expectedStates.count()) { + equals = false; + break; + } + QList args = spy.at(i); + QAbstractAnimation::State st = expectedStates.at(i); + QAbstractAnimation::State actual = qVariantValue(args.value(1)); + if (equals && actual != st) { + equals = false; + break; + } + } + if (!equals) { + const char *stateStrings[] = {"Stopped", "Paused", "Running"}; + QString e,a; + for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) { + if (i < expectedStates.count()) { + int exp = int(expectedStates.at(i)); + if (!e.isEmpty()) + e += QLatin1String(", "); + e += QLatin1String(stateStrings[exp]); + } + if (i < spy.count()) { + QList args = spy.at(i); + QAbstractAnimation::State actual = qVariantValue(args.value(1)); + if (!a.isEmpty()) + a += QLatin1String(", "); + if (int(actual) >= 0 && int(actual) <= 2) { + a += QLatin1String(stateStrings[int(actual)]); + } else { + a += QLatin1String("NaN"); + } + } + + } + qDebug("\n" + "expected (count == %d): %s\n" + "actual (count == %d): %s\n", expectedStates.count(), qPrintable(e), spy.count(), qPrintable(a)); + } + return equals; +} + +void tst_QSequentialAnimationGroup::pauseAndResume() +{ + AnimationObject s_o1; + + // sequence operating on same object/property + QAnimationGroup *sequence = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); + a2_s_o1->setLoopCount(2); + sequence->addAnimation(a1_s_o1); + sequence->addAnimation(a2_s_o1); + sequence->addAnimation(a3_s_o1); + sequence->setLoopCount(2); + + QSignalSpy a1StateChangedSpy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + QSequentialAnimationGroup group; + group.addAnimation(sequence); + + group.start(); + group.pause(); + + // Current time = 1751 + group.setCurrentTime(1751); + QCOMPARE(group.currentTime(), 1751); + QCOMPARE(sequence->currentTime(), 751); + QCOMPARE(sequence->currentLoop(), 1); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 1); + QCOMPARE(a3_s_o1->currentLoop(), 0); + QCOMPARE(a3_s_o1->currentTime(), 1); + + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(sequence->state(), QAnimationGroup::Paused); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused); + + QCOMPARE(a1StateChangedSpy.count(), 5); // Running,Paused,Stopped,Running,Stopped + QCOMPARE(seqStateChangedSpy.count(), 2); // Running,Paused + + QVERIFY(compareStates(a1StateChangedSpy, (StateList() << QAbstractAnimation::Running + << QAbstractAnimation::Paused + << QAbstractAnimation::Stopped + << QAbstractAnimation::Running + << QAbstractAnimation::Stopped))); + + QCOMPARE(qVariantValue(a1StateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(a1StateChangedSpy.at(1).at(1)), + QAnimationGroup::Paused); + QCOMPARE(qVariantValue(a1StateChangedSpy.at(2).at(1)), + QAnimationGroup::Stopped); + QCOMPARE(qVariantValue(a1StateChangedSpy.at(3).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(a1StateChangedSpy.at(4).at(1)), + QAnimationGroup::Stopped); + + QCOMPARE(qVariantValue(seqStateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(seqStateChangedSpy.at(1).at(1)), + QAnimationGroup::Paused); + + group.resume(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(sequence->state(), QAnimationGroup::Running); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a3_s_o1->state(), QAnimationGroup::Running); + + QVERIFY(group.currentTime() >= 1751); + QVERIFY(sequence->currentTime() >= 751); + QCOMPARE(sequence->currentLoop(), 1); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 1); + QCOMPARE(a3_s_o1->currentLoop(), 0); + QVERIFY(a3_s_o1->currentTime() >= 1); + + QCOMPARE(seqStateChangedSpy.count(), 3); // Running,Paused,Running + QCOMPARE(qVariantValue(seqStateChangedSpy.at(2).at(1)), + QAnimationGroup::Running); + + group.pause(); + + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(sequence->state(), QAnimationGroup::Paused); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused); + + QVERIFY(group.currentTime() >= 1751); + QVERIFY(sequence->currentTime() >= 751); + QCOMPARE(sequence->currentLoop(), 1); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 1); + QCOMPARE(a3_s_o1->currentLoop(), 0); + QVERIFY(a3_s_o1->currentTime() >= 1); + + QCOMPARE(seqStateChangedSpy.count(), 4); // Running,Paused,Running,Paused + QCOMPARE(qVariantValue(seqStateChangedSpy.at(3).at(1)), + QAnimationGroup::Paused); + + group.stop(); + + QCOMPARE(seqStateChangedSpy.count(), 5); // Running,Paused,Running,Paused,Stopped + QCOMPARE(qVariantValue(seqStateChangedSpy.at(4).at(1)), + QAnimationGroup::Stopped); +} + +void tst_QSequentialAnimationGroup::restart() +{ + AnimationObject s_o1; + + // sequence operating on same object/property + QAnimationGroup *sequence = new QSequentialAnimationGroup(); + QSignalSpy seqCurrentAnimChangedSpy(sequence, SIGNAL(currentAnimationChanged(QAbstractAnimation*))); + QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + QVariantAnimation *anims[3]; + QSignalSpy *animsStateChanged[3]; + + for (int i = 0; i < 3; i++) { + anims[i] = new QPropertyAnimation(&s_o1, "value"); + anims[i]->setDuration(100); + animsStateChanged[i] = new QSignalSpy(anims[i], SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + } + + anims[1]->setLoopCount(2); + sequence->addAnimation(anims[0]); + sequence->addAnimation(anims[1]); + sequence->addAnimation(anims[2]); + sequence->setLoopCount(2); + + QSequentialAnimationGroup group; + group.addAnimation(sequence); + + group.start(); + + QTest::qWait(500); + + QCOMPARE(group.state(), QAnimationGroup::Running); + + QTest::qWait(300); + QTRY_COMPARE(group.state(), QAnimationGroup::Stopped); + + for (int i = 0; i < 3; i++) { + QCOMPARE(animsStateChanged[i]->count(), 4); + QCOMPARE(qVariantValue(animsStateChanged[i]->at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(animsStateChanged[i]->at(1).at(1)), + QAnimationGroup::Stopped); + QCOMPARE(qVariantValue(animsStateChanged[i]->at(2).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(animsStateChanged[i]->at(3).at(1)), + QAnimationGroup::Stopped); + } + + QCOMPARE(seqStateChangedSpy.count(), 2); + QCOMPARE(qVariantValue(seqStateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(seqStateChangedSpy.at(1).at(1)), + QAnimationGroup::Stopped); + + QCOMPARE(seqCurrentAnimChangedSpy.count(), 6); + for(int i=0; i(seqCurrentAnimChangedSpy.at(i).at(0))); + + group.start(); + + QCOMPARE(animsStateChanged[0]->count(), 5); + QCOMPARE(animsStateChanged[1]->count(), 4); + QCOMPARE(animsStateChanged[2]->count(), 4); + QCOMPARE(seqStateChangedSpy.count(), 3); +} + +void tst_QSequentialAnimationGroup::looping() +{ + AnimationObject s_o1; + AnimationObject s_o2; + AnimationObject s_o3; + + // sequence operating on same object/property + QSequentialAnimationGroup *sequence = new QSequentialAnimationGroup(); + QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); + QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); + + QSignalSpy a1Spy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy a2Spy(a2_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy a3Spy(a3_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy seqSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + a2_s_o1->setLoopCount(2); + sequence->addAnimation(a1_s_o1); + sequence->addAnimation(a2_s_o1); + sequence->addAnimation(a3_s_o1); + sequence->setLoopCount(2); + + QSequentialAnimationGroup group; + QSignalSpy groupSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + group.addAnimation(sequence); + group.setLoopCount(2); + + group.start(); + group.pause(); + + // Current time = 1750 + group.setCurrentTime(1750); + QCOMPARE(group.currentTime(), 1750); + QCOMPARE(sequence->currentTime(), 750); + QCOMPARE(sequence->currentLoop(), 1); + QCOMPARE(a1_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 1); + // this animation is at the beginning because it is the current one inside sequence + QCOMPARE(a3_s_o1->currentLoop(), 0); + QCOMPARE(a3_s_o1->currentTime(), 0); + QCOMPARE(sequence->currentAnimation(), a3_s_o1); + + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(sequence->state(), QAnimationGroup::Paused); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused); + + QCOMPARE(a1Spy.count(), 5); // Running,Paused,Stopped,Running,Stopped + QVERIFY(compareStates(a1Spy, (StateList() << QAbstractAnimation::Running + << QAbstractAnimation::Paused + << QAbstractAnimation::Stopped + << QAbstractAnimation::Running + << QAbstractAnimation::Stopped))); + + QCOMPARE(a2Spy.count(), 4); // Running,Stopped,Running,Stopped + QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running + << QAbstractAnimation::Stopped + << QAbstractAnimation::Running + << QAbstractAnimation::Paused))); + + QCOMPARE(seqSpy.count(), 2); // Running,Paused + QCOMPARE(groupSpy.count(), 2); // Running,Paused + + // Looping, current time = duration + 1 + group.setCurrentTime(group.duration() + 1); + QCOMPARE(group.currentTime(), 1); + QCOMPARE(group.currentLoop(), 1); + QCOMPARE(sequence->currentTime(), 1); + QCOMPARE(sequence->currentLoop(), 0); + QCOMPARE(a1_s_o1->currentTime(), 1); + QCOMPARE(a2_s_o1->currentTime(), 250); + QCOMPARE(a2_s_o1->currentLoop(), 1); + // this animation is at the end because it was run on the previous loop + QCOMPARE(a3_s_o1->currentLoop(), 0); + QCOMPARE(a3_s_o1->currentTime(), 250); + + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(sequence->state(), QAnimationGroup::Paused); + QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused); + QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); + QCOMPARE(a3_s_o1->state(), QAnimationGroup::Stopped); + + QCOMPARE(a1Spy.count(), 7); // Running,Paused,Stopped,Running,Stopped,Running,Stopped + QCOMPARE(a2Spy.count(), 4); // Running, Stopped, Running, Stopped + QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running + << QAbstractAnimation::Stopped + << QAbstractAnimation::Running + << QAbstractAnimation::Paused + << QAbstractAnimation::Stopped))); + QVERIFY(compareStates(seqSpy, (StateList() << QAbstractAnimation::Running + << QAbstractAnimation::Paused + << QAbstractAnimation::Stopped + << QAbstractAnimation::Running + << QAbstractAnimation::Paused))); + QCOMPARE(groupSpy.count(), 2); +} + +void tst_QSequentialAnimationGroup::startDelay() +{ + QSequentialAnimationGroup group; + group.addPause(250); + group.addPause(125); + QCOMPARE(group.totalDuration(), 375); + + QEventLoop loop; + QObject::connect(&group, SIGNAL(finished()), &loop, SLOT(quit())); + + QTime time; + time.start(); + group.start(); + loop.exec(); + + QVERIFY(time.elapsed() >= 375); + QVERIFY(time.elapsed() < 1000); +} + +void tst_QSequentialAnimationGroup::clearGroup() +{ + QSequentialAnimationGroup group; + + for (int i = 0; i < 10; ++i) { + QSequentialAnimationGroup *subGroup = new QSequentialAnimationGroup(&group); + group.addPause(100); + subGroup->addPause(10); + } + + QCOMPARE(group.animationCount(), 20); + + int count = group.animationCount(); + QPointer *children = new QPointer[count]; + for (int i = 0; i < count; ++i) { + QVERIFY(group.animationAt(i) != 0); + children[i] = group.animationAt(i); + } + + group.clearAnimations(); + QCOMPARE(group.animationCount(), 0); + QCOMPARE(group.currentTime(), 0); + for (int i = 0; i < count; ++i) + QCOMPARE(children[i], QPointer()); + + delete[] children; +} + +void tst_QSequentialAnimationGroup::groupWithZeroDurationAnimations() +{ + QObject o; + QObject o2; + + o.setProperty("myProperty", 42); + o.setProperty("myOtherProperty", 13); + o2.setProperty("myProperty", 42); + o2.setProperty("myOtherProperty", 13); + + QSequentialAnimationGroup group; + + QVariantAnimation *a1 = new QPropertyAnimation(&o, "myProperty"); + a1->setDuration(0); + a1->setEndValue(43); + group.addAnimation(a1); + + //this should just run fine and change nothing + group.setCurrentTime(0); + QCOMPARE(group.currentAnimation(), a1); + + QVariantAnimation *a2 = new QPropertyAnimation(&o2, "myOtherProperty"); + a2->setDuration(500); + a2->setEndValue(31); + group.addAnimation(a2); + + QVariantAnimation *a3 = new QPropertyAnimation(&o, "myProperty"); + a3->setDuration(0); + a3->setEndValue(44); + group.addAnimation(a3); + + QVariantAnimation *a4 = new QPropertyAnimation(&o, "myOtherProperty"); + a4->setDuration(250); + a4->setEndValue(75); + group.addAnimation(a4); + + QVariantAnimation *a5 = new QPropertyAnimation(&o2, "myProperty"); + a5->setDuration(0); + a5->setEndValue(12); + group.addAnimation(a5); + + QCOMPARE(o.property("myProperty").toInt(), 42); + QCOMPARE(o.property("myOtherProperty").toInt(), 13); + QCOMPARE(o2.property("myProperty").toInt(), 42); + QCOMPARE(o2.property("myOtherProperty").toInt(), 13); + + + group.start(); + + QCOMPARE(o.property("myProperty").toInt(), 43); + QCOMPARE(o.property("myOtherProperty").toInt(), 13); + QCOMPARE(o2.property("myProperty").toInt(), 42); + QCOMPARE(o2.property("myOtherProperty").toInt(), 13); + + QTest::qWait(50); + + int o2val = o2.property("myOtherProperty").toInt(); + QVERIFY(o2val > 13); + QVERIFY(o2val < 31); + QCOMPARE(o.property("myProperty").toInt(), 43); + QCOMPARE(o.property("myOtherProperty").toInt(), 13); + + QTest::qWait(500); + + QCOMPARE(o.property("myProperty").toInt(), 44); + QCOMPARE(o2.property("myProperty").toInt(), 42); + QCOMPARE(o2.property("myOtherProperty").toInt(), 31); + QCOMPARE(a1->state(), QAnimationGroup::Stopped); + QCOMPARE(a2->state(), QAnimationGroup::Stopped); + QCOMPARE(a3->state(), QAnimationGroup::Stopped); + QCOMPARE(a4->state(), QAnimationGroup::Running); + QCOMPARE(a5->state(), QAnimationGroup::Stopped); + QCOMPARE(group.state(), QAnimationGroup::Running); + QTest::qWait(500); + + QTRY_COMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(o.property("myProperty").toInt(), 44); + QCOMPARE(o.property("myOtherProperty").toInt(), 75); + QCOMPARE(o2.property("myProperty").toInt(), 12); + QCOMPARE(o2.property("myOtherProperty").toInt(), 31); + QCOMPARE(a1->state(), QAnimationGroup::Stopped); + QCOMPARE(a2->state(), QAnimationGroup::Stopped); + QCOMPARE(a3->state(), QAnimationGroup::Stopped); + QCOMPARE(a4->state(), QAnimationGroup::Stopped); + QCOMPARE(a5->state(), QAnimationGroup::Stopped); +} + +void tst_QSequentialAnimationGroup::propagateGroupUpdateToChildren() +{ + // this test verifies if group state changes are updating its children correctly + QSequentialAnimationGroup group; + + QObject o; + o.setProperty("ole", 42); + QCOMPARE(o.property("ole").toInt(), 42); + + QPropertyAnimation anim1(&o, "ole"); + anim1.setEndValue(43); + anim1.setDuration(100); + QVERIFY(!anim1.currentValue().isValid()); + QCOMPARE(anim1.currentValue().toInt(), 0); + QCOMPARE(o.property("ole").toInt(), 42); + + TestAnimation anim2; + anim2.setStartValue(0); + anim2.setEndValue(100); + anim2.setDuration(200); + + QVERIFY(anim2.currentValue().isValid()); + QCOMPARE(anim2.currentValue().toInt(), 0); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + + group.start(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + group.pause(); + + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(anim1.state(), QAnimationGroup::Paused); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + group.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); +} + +void tst_QSequentialAnimationGroup::updateChildrenWithRunningGroup() +{ + // assert that its possible to modify a child's state directly while their group is running + QSequentialAnimationGroup group; + + TestAnimation anim; + anim.setStartValue(0); + anim.setEndValue(100); + anim.setDuration(200); + + QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + QCOMPARE(groupStateChangedSpy.count(), 0); + QCOMPARE(childStateChangedSpy.count(), 0); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim.state(), QAnimationGroup::Stopped); + + group.addAnimation(&anim); + + group.start(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim.state(), QAnimationGroup::Running); + + QCOMPARE(groupStateChangedSpy.count(), 1); + QCOMPARE(childStateChangedSpy.count(), 1); + + QCOMPARE(qVariantValue(groupStateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(childStateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + + // starting directly a running child will not have any effect + anim.start(); + + QCOMPARE(groupStateChangedSpy.count(), 1); + QCOMPARE(childStateChangedSpy.count(), 1); + + anim.pause(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim.state(), QAnimationGroup::Paused); + + // in the animation stops directly, the group will still be running + anim.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim.state(), QAnimationGroup::Stopped); +} + +void tst_QSequentialAnimationGroup::deleteChildrenWithRunningGroup() +{ + // test if children can be activated when their group is stopped + QSequentialAnimationGroup group; + + QVariantAnimation *anim1 = new TestAnimation; + anim1->setStartValue(0); + anim1->setEndValue(100); + anim1->setDuration(200); + group.addAnimation(anim1); + + QCOMPARE(group.duration(), anim1->duration()); + + group.start(); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim1->state(), QAnimationGroup::Running); + + QTest::qWait(50); + QVERIFY(group.currentTime() > 0); + + delete anim1; + QCOMPARE(group.animationCount(), 0); + QCOMPARE(group.duration(), 0); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(group.currentTime(), 0); //that's the invariant +} + +void tst_QSequentialAnimationGroup::startChildrenWithStoppedGroup() +{ + // test if children can be activated when their group is stopped + QSequentialAnimationGroup group; + + TestAnimation anim1; + anim1.setStartValue(0); + anim1.setEndValue(100); + anim1.setDuration(200); + + TestAnimation anim2; + anim2.setStartValue(0); + anim2.setEndValue(100); + anim2.setDuration(200); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + + group.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + anim1.start(); + anim2.start(); + anim2.pause(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Paused); +} + +void tst_QSequentialAnimationGroup::stopGroupWithRunningChild() +{ + // children that started independently will not be affected by a group stop + QSequentialAnimationGroup group; + + TestAnimation anim1; + anim1.setStartValue(0); + anim1.setEndValue(100); + anim1.setDuration(200); + + TestAnimation anim2; + anim2.setStartValue(0); + anim2.setEndValue(100); + anim2.setDuration(200); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); + + group.addAnimation(&anim1); + group.addAnimation(&anim2); + + anim1.start(); + anim2.start(); + anim2.pause(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Paused); + + group.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Running); + QCOMPARE(anim2.state(), QAnimationGroup::Paused); + + anim1.stop(); + anim2.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1.state(), QAnimationGroup::Stopped); + QCOMPARE(anim2.state(), QAnimationGroup::Stopped); +} + +void tst_QSequentialAnimationGroup::startGroupWithRunningChild() +{ + // as the group has precedence over its children, starting a group will restart all the children + QSequentialAnimationGroup group; + + TestAnimation *anim1 = new TestAnimation(); + anim1->setStartValue(0); + anim1->setEndValue(100); + anim1->setDuration(200); + + TestAnimation *anim2 = new TestAnimation(); + anim2->setStartValue(0); + anim2->setEndValue(100); + anim2->setDuration(200); + + QSignalSpy stateChangedSpy1(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QSignalSpy stateChangedSpy2(anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + QCOMPARE(stateChangedSpy1.count(), 0); + QCOMPARE(stateChangedSpy2.count(), 0); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1->state(), QAnimationGroup::Stopped); + QCOMPARE(anim2->state(), QAnimationGroup::Stopped); + + group.addAnimation(anim1); + group.addAnimation(anim2); + + anim1->start(); + anim2->start(); + anim2->pause(); + + QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running))); + + QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running + << QAbstractAnimation::Paused))); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1->state(), QAnimationGroup::Running); + QCOMPARE(anim2->state(), QAnimationGroup::Paused); + + group.start(); + + QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running + << QAbstractAnimation::Stopped + << QAbstractAnimation::Running))); + QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running + << QAbstractAnimation::Paused))); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim1->state(), QAnimationGroup::Running); + QCOMPARE(anim2->state(), QAnimationGroup::Paused); + + QTest::qWait(300); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim1->state(), QAnimationGroup::Stopped); + QCOMPARE(anim2->state(), QAnimationGroup::Running); + + QCOMPARE(stateChangedSpy2.count(), 4); + QCOMPARE(qVariantValue(stateChangedSpy2.at(2).at(1)), + QAnimationGroup::Stopped); + QCOMPARE(qVariantValue(stateChangedSpy2.at(3).at(1)), + QAnimationGroup::Running); + + group.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(anim1->state(), QAnimationGroup::Stopped); + QCOMPARE(anim2->state(), QAnimationGroup::Stopped); +} + +void tst_QSequentialAnimationGroup::zeroDurationAnimation() +{ + QSequentialAnimationGroup group; + + TestAnimation *anim1 = new TestAnimation(); + anim1->setStartValue(0); + anim1->setEndValue(100); + anim1->setDuration(0); + + TestAnimation *anim2 = new TestAnimation(); + anim2->setStartValue(0); + anim2->setEndValue(100); + anim2->setDuration(100); + + AnimationObject o1; + QPropertyAnimation *anim3 = new QPropertyAnimation(&o1, "value"); + anim3->setEndValue(100); + anim3->setDuration(0); + + QSignalSpy stateChangedSpy(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + group.addAnimation(anim1); + group.addAnimation(anim2); + group.addAnimation(anim3); + group.setLoopCount(2); + group.start(); + + QCOMPARE(stateChangedSpy.count(), 2); + QCOMPARE(qVariantValue(stateChangedSpy.at(0).at(1)), + QAnimationGroup::Running); + QCOMPARE(qVariantValue(stateChangedSpy.at(1).at(1)), + QAnimationGroup::Stopped); + + QCOMPARE(anim1->state(), QAnimationGroup::Stopped); + QCOMPARE(anim2->state(), QAnimationGroup::Running); + QCOMPARE(group.state(), QAnimationGroup::Running); + + //now let's try to seek to the next loop + group.setCurrentTime(group.duration() + 1); + QCOMPARE(anim1->state(), QAnimationGroup::Stopped); + QCOMPARE(anim2->state(), QAnimationGroup::Running); + QCOMPARE(anim3->state(), QAnimationGroup::Stopped); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(o1.value(), 100); //anim3 should have been run +} + +void tst_QSequentialAnimationGroup::stopUncontrolledAnimations() +{ + QSequentialAnimationGroup group; + + AnimationObject o1; + UncontrolledAnimation notTimeDriven(&o1, "value"); + QCOMPARE(notTimeDriven.totalDuration(), -1); + + TestAnimation loopsForever; + loopsForever.setStartValue(0); + loopsForever.setEndValue(100); + loopsForever.setDuration(100); + loopsForever.setLoopCount(-1); + + group.addAnimation(¬TimeDriven); + group.addAnimation(&loopsForever); + + group.start(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running); + QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped); + + notTimeDriven.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); + QCOMPARE(loopsForever.state(), QAnimationGroup::Running); + + loopsForever.stop(); + + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); + QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped); +} + +void tst_QSequentialAnimationGroup::finishWithUncontrolledAnimation() +{ + AnimationObject o1; + + //1st case: + //first we test a group with one uncontrolled animation + QSequentialAnimationGroup group; + UncontrolledAnimation notTimeDriven(&o1, "value", &group); + QSignalSpy spy(&group, SIGNAL(finished())); + + group.start(); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running); + QCOMPARE(group.currentTime(), 0); + QCOMPARE(notTimeDriven.currentTime(), 0); + + QTest::qWait(300); //wait for the end of notTimeDriven + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); + const int actualDuration = notTimeDriven.currentTime(); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(group.currentTime(), actualDuration); + QCOMPARE(spy.count(), 1); + + //2nd case: + // lets make sure the seeking will work again + spy.clear(); + QPropertyAnimation anim(&group); + QSignalSpy animStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + + group.setCurrentTime(300); + QCOMPARE(group.state(), QAnimationGroup::Stopped); + QCOMPARE(notTimeDriven.currentTime(), actualDuration); + QCOMPARE(group.currentAnimation(), &anim); + + //3rd case: + //now let's add a perfectly defined animation at the end + QCOMPARE(animStateChangedSpy.count(), 0); + group.start(); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running); + QCOMPARE(group.currentTime(), 0); + QCOMPARE(notTimeDriven.currentTime(), 0); + + QCOMPARE(animStateChangedSpy.count(), 0); + + QTest::qWait(300); //wait for the end of notTimeDriven + QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim.state(), QAnimationGroup::Running); + QCOMPARE(group.currentAnimation(), &anim); + QCOMPARE(animStateChangedSpy.count(), 1); + QTest::qWait(300); //wait for the end of anim + + QCOMPARE(anim.state(), QAnimationGroup::Stopped); + QCOMPARE(anim.currentTime(), anim.duration()); + + //we should simply be at the end + QCOMPARE(spy.count(), 1); + QCOMPARE(animStateChangedSpy.count(), 2); + QCOMPARE(group.currentTime(), notTimeDriven.currentTime() + anim.currentTime()); +} + +void tst_QSequentialAnimationGroup::addRemoveAnimation() +{ + //this test is specific to the sequential animation group + QSequentialAnimationGroup group; + + QCOMPARE(group.duration(), 0); + QCOMPARE(group.currentTime(), 0); + QVariantAnimation *anim1 = new QPropertyAnimation; + group.addAnimation(anim1); + QCOMPARE(group.duration(), 250); + QCOMPARE(group.currentTime(), 0); + QCOMPARE(group.currentAnimation(), anim1); + + //let's append an animation + QVariantAnimation *anim2 = new QPropertyAnimation; + group.addAnimation(anim2); + QCOMPARE(group.duration(), 500); + QCOMPARE(group.currentTime(), 0); + QCOMPARE(group.currentAnimation(), anim1); + + //let's prepend an animation + QVariantAnimation *anim0 = new QPropertyAnimation; + group.insertAnimationAt(0, anim0); + QCOMPARE(group.duration(), 750); + QCOMPARE(group.currentTime(), 0); + QCOMPARE(group.currentAnimation(), anim0); //anim0 has become the new currentAnimation + + group.setCurrentTime(300); //anim0 | anim1 | anim2 + QCOMPARE(group.currentTime(), 300); + QCOMPARE(group.currentAnimation(), anim1); + QCOMPARE(anim1->currentTime(), 50); + + group.removeAnimation(anim0); //anim1 | anim2 + QCOMPARE(group.currentTime(), 50); + QCOMPARE(group.currentAnimation(), anim1); + QCOMPARE(anim1->currentTime(), 50); + + group.setCurrentTime(0); + group.insertAnimationAt(0, anim0); //anim0 | anim1 | anim2 + group.setCurrentTime(300); + QCOMPARE(group.currentTime(), 300); + QCOMPARE(group.currentAnimation(), anim1); + QCOMPARE(anim1->currentTime(), 50); + + group.removeAnimation(anim1); //anim0 | anim2 + QCOMPARE(group.currentTime(), 250); + QCOMPARE(group.currentAnimation(), anim2); + QCOMPARE(anim0->currentTime(), 250); +} + +void tst_QSequentialAnimationGroup::currentAnimation() +{ + QSequentialAnimationGroup group; + QVERIFY(group.currentAnimation() == 0); + + QPropertyAnimation anim; + anim.setDuration(0); + group.addAnimation(&anim); + QCOMPARE(group.currentAnimation(), &anim); +} + +void tst_QSequentialAnimationGroup::currentAnimationWithZeroDuration() +{ + QSequentialAnimationGroup group; + QVERIFY(group.currentAnimation() == 0); + + QPropertyAnimation zero1; + zero1.setDuration(0); + QPropertyAnimation zero2; + zero2.setDuration(0); + + QPropertyAnimation anim; + + QPropertyAnimation zero3; + zero3.setDuration(0); + QPropertyAnimation zero4; + zero4.setDuration(0); + + + group.addAnimation(&zero1); + group.addAnimation(&zero2); + group.addAnimation(&anim); + group.addAnimation(&zero3); + group.addAnimation(&zero4); + + QCOMPARE(group.currentAnimation(), &zero1); + + group.setCurrentTime(0); + QCOMPARE(group.currentAnimation(), &anim); + + group.setCurrentTime(group.duration()); + QCOMPARE(group.currentAnimation(), &zero4); + + group.setDirection(QAbstractAnimation::Backward); + + group.setCurrentTime(0); + QCOMPARE(group.currentAnimation(), &zero1); + + group.setCurrentTime(group.duration()); + QCOMPARE(group.currentAnimation(), &anim); +} + +void tst_QSequentialAnimationGroup::insertAnimation() +{ + QSequentialAnimationGroup group; + group.setLoopCount(2); + QPropertyAnimation *anim = new QPropertyAnimation(&group); + QCOMPARE(group.duration(), anim->duration()); + group.setCurrentTime(300); + QCOMPARE(group.currentLoop(), 1); + + //this will crash if the sequential group calls duration on the created animation + new QPropertyAnimation(&group); +} + + +class SequentialAnimationGroup : public QSequentialAnimationGroup +{ + Q_OBJECT +public slots: + void clearAnimations() + { + QSequentialAnimationGroup::clearAnimations(); + } + + void refill() + { + stop(); + clearAnimations(); + new QPropertyAnimation(this); + start(); + } + +}; + + +void tst_QSequentialAnimationGroup::clearAnimations() +{ + SequentialAnimationGroup group; + QPointer anim1 = new QPropertyAnimation(&group); + group.connect(anim1, SIGNAL(finished()), SLOT(clearAnimations())); + new QPropertyAnimation(&group); + QCOMPARE(group.animationCount(), 2); + + group.start(); + QTest::qWait(anim1->duration() + 100); + QCOMPARE(group.animationCount(), 0); + QCOMPARE(group.state(), QAbstractAnimation::Stopped); + QCOMPARE(group.currentTime(), 0); + + anim1 = new QPropertyAnimation(&group); + group.connect(anim1, SIGNAL(finished()), SLOT(refill())); + group.start(); + QTest::qWait(anim1->duration() + 100); + QVERIFY(anim1 == 0); //anim1 should have been deleted + QCOMPARE(group.state(), QAbstractAnimation::Running); +} + +QTEST_MAIN(tst_QSequentialAnimationGroup) +#include "tst_qsequentialanimationgroup.moc" diff --git a/tests/auto/qstate/qstate.pro b/tests/auto/qstate/qstate.pro new file mode 100644 index 0000000..9131fa8 --- /dev/null +++ b/tests/auto/qstate/qstate.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT = core +SOURCES += tst_qstate.cpp + + diff --git a/tests/auto/qstate/tst_qstate.cpp b/tests/auto/qstate/tst_qstate.cpp new file mode 100644 index 0000000..75b1905 --- /dev/null +++ b/tests/auto/qstate/tst_qstate.cpp @@ -0,0 +1,340 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include + +#include "qstate.h" +#include "qstatemachine.h" +#include "qsignaltransition.h" + +// Will try to wait for the condition while allowing event processing +#define QTRY_COMPARE(__expr, __expected) \ + do { \ + const int __step = 50; \ + const int __timeout = 5000; \ + if ((__expr) != (__expected)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QCOMPARE(__expr, __expected); \ + } while(0) + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QState : public QObject +{ + Q_OBJECT + +public: + tst_QState(); + virtual ~tst_QState(); + +private slots: +#if 0 + void test(); +#endif + void assignProperty(); + void assignPropertyTwice(); + void historyInitialState(); + +private: + bool functionCalled; +}; + +tst_QState::tst_QState() : functionCalled(false) +{ +} + +tst_QState::~tst_QState() +{ +} + +#if 0 +void tst_QState::test() +{ + QStateMachine machine; + QState *s1 = new QState(machine.rootState()); + + QCOMPARE(s1->machine(), &machine); + QCOMPARE(s1->parentState(), machine.rootState()); + QCOMPARE(s1->initialState(), (QState*)0); + QVERIFY(s1->childStates().isEmpty()); + QVERIFY(s1->transitions().isEmpty()); + + QCOMPARE(s1->isFinal(), false); + s1->setFinal(true); + QCOMPARE(s1->isFinal(), true); + s1->setFinal(false); + QCOMPARE(s1->isFinal(), false); + + QCOMPARE(s1->isParallel(), false); + s1->setParallel(true); + QCOMPARE(s1->isParallel(), true); + s1->setParallel(false); + QCOMPARE(s1->isParallel(), false); + + QCOMPARE(s1->isAtomic(), true); + QCOMPARE(s1->isCompound(), false); + QCOMPARE(s1->isComplex(), false); + + QState *s11 = new QState(s1); + QCOMPARE(s11->parentState(), s1); + QCOMPARE(s11->isAtomic(), true); + QCOMPARE(s11->isCompound(), false); + QCOMPARE(s11->isComplex(), false); + QCOMPARE(s11->machine(), s1->machine()); + QVERIFY(s11->isDescendantOf(s1)); + + QCOMPARE(s1->initialState(), (QState*)0); + QCOMPARE(s1->childStates().size(), 1); + QCOMPARE(s1->childStates().at(0), s11); + + QCOMPARE(s1->isAtomic(), false); + QCOMPARE(s1->isCompound(), true); + QCOMPARE(s1->isComplex(), true); + + s1->setParallel(true); + QCOMPARE(s1->isAtomic(), false); + QCOMPARE(s1->isCompound(), false); + QCOMPARE(s1->isComplex(), true); + + QState *s12 = new QState(s1); + QCOMPARE(s12->parentState(), s1); + QCOMPARE(s12->isAtomic(), true); + QCOMPARE(s12->isCompound(), false); + QCOMPARE(s12->isComplex(), false); + QCOMPARE(s12->machine(), s1->machine()); + QVERIFY(s12->isDescendantOf(s1)); + QVERIFY(!s12->isDescendantOf(s11)); + + QCOMPARE(s1->initialState(), (QState*)0); + QCOMPARE(s1->childStates().size(), 2); + QCOMPARE(s1->childStates().at(0), s11); + QCOMPARE(s1->childStates().at(1), s12); + + QCOMPARE(s1->isAtomic(), false); + QCOMPARE(s1->isCompound(), false); + QCOMPARE(s1->isComplex(), true); + + s1->setParallel(false); + QCOMPARE(s1->isAtomic(), false); + QCOMPARE(s1->isCompound(), true); + QCOMPARE(s1->isComplex(), true); + + s1->setInitialState(s11); + QCOMPARE(s1->initialState(), s11); + + s1->setInitialState(0); + QCOMPARE(s1->initialState(), (QState*)0); + + s1->setInitialState(s12); + QCOMPARE(s1->initialState(), s12); + + QState *s13 = new QState(); + s1->setInitialState(s13); + QCOMPARE(s13->parentState(), s1); + QCOMPARE(s1->childStates().size(), 3); + QCOMPARE(s1->childStates().at(0), s11); + QCOMPARE(s1->childStates().at(1), s12); + QCOMPARE(s1->childStates().at(2), s13); + QVERIFY(s13->isDescendantOf(s1)); + + QVERIFY(s12->childStates().isEmpty()); + + QState *s121 = new QState(s12); + QCOMPARE(s121->parentState(), s12); + QCOMPARE(s121->isAtomic(), true); + QCOMPARE(s121->isCompound(), false); + QCOMPARE(s121->isComplex(), false); + QCOMPARE(s121->machine(), s12->machine()); + QVERIFY(s121->isDescendantOf(s12)); + QVERIFY(s121->isDescendantOf(s1)); + QVERIFY(!s121->isDescendantOf(s11)); + + QCOMPARE(s12->childStates().size(), 1); + QCOMPARE(s12->childStates().at(0), (QState*)s121); + + QCOMPARE(s1->childStates().size(), 3); + QCOMPARE(s1->childStates().at(0), s11); + QCOMPARE(s1->childStates().at(1), s12); + QCOMPARE(s1->childStates().at(2), s13); + + s11->addTransition(s12); + QCOMPARE(s11->transitions().size(), 1); + QCOMPARE(s11->transitions().at(0)->sourceState(), s11); + QCOMPARE(s11->transitions().at(0)->targetStates().size(), 1); + QCOMPARE(s11->transitions().at(0)->targetStates().at(0), s12); + QCOMPARE(s11->transitions().at(0)->eventType(), QEvent::None); + + QState *s14 = new QState(); + s12->addTransition(QList() << s13 << s14); + QCOMPARE(s12->transitions().size(), 1); + QCOMPARE(s12->transitions().at(0)->sourceState(), s12); + QCOMPARE(s12->transitions().at(0)->targetStates().size(), 2); + QCOMPARE(s12->transitions().at(0)->targetStates().at(0), s13); + QCOMPARE(s12->transitions().at(0)->targetStates().at(1), s14); + QCOMPARE(s12->transitions().at(0)->eventType(), QEvent::None); + + s13->addTransition(this, SIGNAL(destroyed()), s14); + QCOMPARE(s13->transitions().size(), 1); + QCOMPARE(s13->transitions().at(0)->sourceState(), s13); + QCOMPARE(s13->transitions().at(0)->targetStates().size(), 1); + QCOMPARE(s13->transitions().at(0)->targetStates().at(0), s14); + QCOMPARE(s13->transitions().at(0)->eventType(), QEvent::Signal); + QVERIFY(qobject_cast(s13->transitions().at(0)) != 0); + + delete s13->transitions().at(0); + QCOMPARE(s13->transitions().size(), 0); + + s12->addTransition(this, SIGNAL(destroyed()), s11); + QCOMPARE(s12->transitions().size(), 2); +} +#endif + +class TestClass: public QObject +{ + Q_OBJECT +public: + TestClass() : called(false) {} + bool called; + +public slots: + void slot() { called = true; } + + +}; + +void tst_QState::assignProperty() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("fooBar", 10); + + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(object, "fooBar", 20); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(object->property("fooBar").toInt(), 20); +} + +void tst_QState::assignPropertyTwice() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("fooBar", 10); + + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(object, "fooBar", 20); + s1->assignProperty(object, "fooBar", 30); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(object->property("fooBar").toInt(), 30); +} + +class EventTestTransition: public QAbstractTransition +{ +public: + EventTestTransition(QEvent::Type type, QState *targetState) + : QAbstractTransition(QList() << targetState), m_type(type) + { + } + +protected: + bool eventTest(QEvent *e) + { + return e->type() == m_type; + } + + void onTransition(QEvent *) {} + +private: + QEvent::Type m_type; + +}; + +void tst_QState::historyInitialState() +{ + QStateMachine machine; + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + QHistoryState *h1 = new QHistoryState(s2); + + s2->setInitialState(h1); + + QState *s3 = new QState(s2); + h1->setDefaultState(s3); + + QState *s4 = new QState(s2); + + s1->addTransition(new EventTestTransition(QEvent::User, s2)); + s2->addTransition(new EventTestTransition(QEvent::User, s1)); + s3->addTransition(new EventTestTransition(QEvent::Type(QEvent::User+1), s4)); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s3)); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s3)); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User+1))); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s4)); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s4)); +} + + +QTEST_MAIN(tst_QState) +#include "tst_qstate.moc" diff --git a/tests/auto/qstatemachine/qstatemachine.pro b/tests/auto/qstatemachine/qstatemachine.pro new file mode 100644 index 0000000..e5b32b5 --- /dev/null +++ b/tests/auto/qstatemachine/qstatemachine.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +QT = core gui +SOURCES += tst_qstatemachine.cpp + diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp new file mode 100644 index 0000000..40c01bd --- /dev/null +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -0,0 +1,3548 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "qstatemachine.h" +#include "qstate.h" +#include "qhistorystate.h" +#include "qkeyeventtransition.h" +#include "qmouseeventtransition.h" +#include "private/qstate_p.h" +#include "private/qstatemachine_p.h" + +// Will try to wait for the condition while allowing event processing +#define QTRY_COMPARE(__expr, __expected) \ + do { \ + const int __step = 50; \ + const int __timeout = 5000; \ + if ((__expr) != (__expected)) { \ + QTest::qWait(0); \ + } \ + for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \ + QTest::qWait(__step); \ + } \ + QCOMPARE(__expr, __expected); \ + } while(0) + +//TESTED_CLASS= +//TESTED_FILES= + +static int globalTick; + +// Run exec for a maximum of TIMEOUT msecs +#define QCOREAPPLICATION_EXEC(TIMEOUT) \ +{ \ + QTimer timer; \ + timer.setSingleShot(true); \ + timer.setInterval(TIMEOUT); \ + timer.start(); \ + connect(&timer, SIGNAL(timeout()), QCoreApplication::instance(), SLOT(quit())); \ + QCoreApplication::exec(); \ +} + +class tst_QStateMachine : public QObject +{ + Q_OBJECT +public: + tst_QStateMachine(); + virtual ~tst_QStateMachine(); + +private slots: + void init(); + void cleanup(); + + void rootState(); + void addAndRemoveState(); + void stateEntryAndExit(); + void assignProperty(); + void assignPropertyWithAnimation(); + void postEvent(); + void stateFinished(); + void parallelStates(); + void allSourceToTargetConfigurations(); + void signalTransitions(); + void eventTransitions(); + void historyStates(); + void startAndStop(); + void targetStateWithNoParent(); + void targetStateDeleted(); + void transitionToRootState(); + void transitionEntersParent(); + + void defaultErrorState(); + void customGlobalErrorState(); + void customLocalErrorStateInBrokenState(); + void customLocalErrorStateInOtherState(); + void customLocalErrorStateInParentOfBrokenState(); + void customLocalErrorStateOverridesParent(); + void errorStateHasChildren(); + void errorStateHasErrors(); + void errorStateIsRootState(); + void errorStateEntersParentFirst(); + void customErrorStateIsNull(); + void clearError(); + void historyStateHasNowhereToGo(); + void historyStateAsInitialState(); + void brokenStateIsNeverEntered(); + void customErrorStateNotInGraph(); + void transitionToStateNotInGraph(); + void restoreProperties(); + + void defaultGlobalRestorePolicy(); + void globalRestorePolicySetToRestore(); + void globalRestorePolicySetToDoNotRestore(); + + //void restorePolicyNotInherited(); + //void mixedRestoreProperties(); + //void setRestorePolicyToDoNotRestore(); + //void setGlobalRestorePolicyToGlobalRestore(); + //void restorePolicyOnChildState(); + + void transitionWithParent(); + void transitionsFromParallelStateWithNoChildren(); + void parallelStateTransition(); + void parallelStateAssignmentsDone(); + void nestedRestoreProperties(); + void nestedRestoreProperties2(); + + void simpleAnimation(); + void twoAnimations(); + void twoAnimatedTransitions(); + void playAnimationTwice(); + void nestedTargetStateForAnimation(); + void animatedGlobalRestoreProperty(); + void specificTargetValueOfAnimation(); + + void addDefaultAnimation(); + void addDefaultAnimationWithUnusedAnimation(); + void removeDefaultAnimation(); + void overrideDefaultAnimationWithSpecific(); + +// void addDefaultAnimationForSource(); +// void addDefaultAnimationForTarget(); +// void removeDefaultAnimationForSource(); +// void removeDefaultAnimationForTarget(); +// void overrideDefaultAnimationWithSource(); +// void overrideDefaultAnimationWithTarget(); +// void overrideDefaultSourceAnimationWithSpecific(); +// void overrideDefaultTargetAnimationWithSpecific(); +// void overrideDefaultTargetAnimationWithSource(); +}; + +tst_QStateMachine::tst_QStateMachine() +{ +} + +tst_QStateMachine::~tst_QStateMachine() +{ +} + +class TestState : public QState +{ +public: + enum Event { + Entry, + Exit + }; + TestState(QState *parent) + : QState(parent) {} + QList > events; +protected: + virtual void onEntry(QEvent *) { + events.append(qMakePair(globalTick++, Entry)); + } + virtual void onExit(QEvent *) { + events.append(qMakePair(globalTick++, Exit)); + } +}; + +class TestTransition : public QAbstractTransition +{ +public: + TestTransition(QAbstractState *target) + : QAbstractTransition(QList() << target) {} + QList triggers; +protected: + virtual bool eventTest(QEvent *) { + return true; + } + virtual void onTransition(QEvent *) { + triggers.append(globalTick++); + } +}; + +void tst_QStateMachine::init() +{ +} + +void tst_QStateMachine::cleanup() +{ +} + +class EventTransition : public QAbstractTransition +{ +public: + EventTransition(QEvent::Type type, QAbstractState *target, QState *parent = 0) + : QAbstractTransition(QList() << target, parent), m_type(type) {} +protected: + virtual bool eventTest(QEvent *e) { + return (e->type() == m_type); + } + virtual void onTransition(QEvent *) {} +private: + QEvent::Type m_type; +}; + +void tst_QStateMachine::transitionToRootState() +{ + QStateMachine machine; + + QState *initialState = new QState(); + machine.addState(initialState); + machine.setInitialState(initialState); + + QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::setTargetStates: root state cannot be target of transition"); + initialState->addTransition(new EventTransition(QEvent::User, machine.rootState())); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(initialState)); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(initialState)); +} + +void tst_QStateMachine::transitionEntersParent() +{ + QStateMachine machine; + + QObject *entryController = new QObject(&machine); + entryController->setObjectName("entryController"); + entryController->setProperty("greatGrandParentEntered", false); + entryController->setProperty("grandParentEntered", false); + entryController->setProperty("parentEntered", false); + entryController->setProperty("stateEntered", false); + + QState *greatGrandParent = new QState(); + greatGrandParent->setObjectName("grandParent"); + greatGrandParent->assignProperty(entryController, "greatGrandParentEntered", true); + machine.addState(greatGrandParent); + machine.setInitialState(greatGrandParent); + + QState *grandParent = new QState(greatGrandParent); + grandParent->setObjectName("grandParent"); + grandParent->assignProperty(entryController, "grandParentEntered", true); + + QState *parent = new QState(grandParent); + parent->setObjectName("parent"); + parent->assignProperty(entryController, "parentEntered", true); + + QState *state = new QState(parent); + state->setObjectName("state"); + state->assignProperty(entryController, "stateEntered", true); + + QState *initialStateOfGreatGrandParent = new QState(greatGrandParent); + initialStateOfGreatGrandParent->setObjectName("initialStateOfGreatGrandParent"); + greatGrandParent->setInitialState(initialStateOfGreatGrandParent); + + initialStateOfGreatGrandParent->addTransition(new EventTransition(QEvent::User, state)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), true); + QCOMPARE(entryController->property("grandParentEntered").toBool(), false); + QCOMPARE(entryController->property("parentEntered").toBool(), false); + QCOMPARE(entryController->property("stateEntered").toBool(), false); + QCOMPARE(machine.configuration().count(), 2); + QVERIFY(machine.configuration().contains(greatGrandParent)); + QVERIFY(machine.configuration().contains(initialStateOfGreatGrandParent)); + + entryController->setProperty("greatGrandParentEntered", false); + entryController->setProperty("grandParentEntered", false); + entryController->setProperty("parentEntered", false); + entryController->setProperty("stateEntered", false); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), false); + QCOMPARE(entryController->property("grandParentEntered").toBool(), true); + QCOMPARE(entryController->property("parentEntered").toBool(), true); + QCOMPARE(entryController->property("stateEntered").toBool(), true); + QCOMPARE(machine.configuration().count(), 4); + QVERIFY(machine.configuration().contains(greatGrandParent)); + QVERIFY(machine.configuration().contains(grandParent)); + QVERIFY(machine.configuration().contains(parent)); + QVERIFY(machine.configuration().contains(state)); +} + +void tst_QStateMachine::defaultErrorState() +{ + QStateMachine machine; + QVERIFY(machine.errorState() != 0); + + QState *brokenState = new QState(); + brokenState->setObjectName("MyInitialState"); + + machine.addState(brokenState); + machine.setInitialState(brokenState); + + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'MyInitialState'"); + + // initialState has no initial state + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); + QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'MyInitialState'")); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(machine.errorState())); +} + +class CustomErrorState: public QState +{ +public: + CustomErrorState(QStateMachine *machine, QState *parent = 0) + : QState(parent), error(QStateMachine::NoError), m_machine(machine) + { + } + + void onEntry(QEvent *) + { + error = m_machine->error(); + errorString = m_machine->errorString(); + } + + QStateMachine::Error error; + QString errorString; + +private: + QStateMachine *m_machine; +}; + +void tst_QStateMachine::customGlobalErrorState() +{ + QStateMachine machine; + + CustomErrorState *customErrorState = new CustomErrorState(&machine); + customErrorState->setObjectName("customErrorState"); + machine.addState(customErrorState); + machine.setErrorState(customErrorState); + + QState *initialState = new QState(); + initialState->setObjectName("initialState"); + machine.addState(initialState); + machine.setInitialState(initialState); + + QState *brokenState = new QState(); + brokenState->setObjectName("brokenState"); + machine.addState(brokenState); + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.errorState(), customErrorState); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(initialState)); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(initialState)); + + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(customErrorState)); + QCOMPARE(customErrorState->error, QStateMachine::NoInitialStateError); + QCOMPARE(customErrorState->errorString, QString::fromLatin1("Missing initial state in compound state 'brokenState'")); + QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); + QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'brokenState'")); +} + +void tst_QStateMachine::customLocalErrorStateInBrokenState() +{ + QStateMachine machine; + CustomErrorState *customErrorState = new CustomErrorState(&machine); + machine.addState(customErrorState); + + QState *initialState = new QState(); + initialState->setObjectName("initialState"); + machine.addState(initialState); + machine.setInitialState(initialState); + + QState *brokenState = new QState(); + brokenState->setObjectName("brokenState"); + machine.addState(brokenState); + brokenState->setErrorState(customErrorState); + + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(customErrorState)); + QCOMPARE(customErrorState->error, QStateMachine::NoInitialStateError); +} + +void tst_QStateMachine::customLocalErrorStateInOtherState() +{ + QStateMachine machine; + CustomErrorState *customErrorState = new CustomErrorState(&machine); + machine.addState(customErrorState); + + QState *initialState = new QState(); + initialState->setObjectName("initialState"); + QTest::ignoreMessage(QtWarningMsg, "QState::setErrorState: error state cannot belong to a different state machine"); + initialState->setErrorState(customErrorState); + machine.addState(initialState); + machine.setInitialState(initialState); + + QState *brokenState = new QState(); + brokenState->setObjectName("brokenState"); + + machine.addState(brokenState); + + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); + + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'brokenState'"); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(machine.errorState())); +} + +void tst_QStateMachine::customLocalErrorStateInParentOfBrokenState() +{ + QStateMachine machine; + CustomErrorState *customErrorState = new CustomErrorState(&machine); + machine.addState(customErrorState); + + QState *initialState = new QState(); + initialState->setObjectName("initialState"); + machine.addState(initialState); + machine.setInitialState(initialState); + + QState *parentOfBrokenState = new QState(); + machine.addState(parentOfBrokenState); + parentOfBrokenState->setObjectName("parentOfBrokenState"); + parentOfBrokenState->setErrorState(customErrorState); + + QState *brokenState = new QState(parentOfBrokenState); + brokenState->setObjectName("brokenState"); + parentOfBrokenState->setInitialState(brokenState); + + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(customErrorState)); +} + +void tst_QStateMachine::customLocalErrorStateOverridesParent() +{ + QStateMachine machine; + CustomErrorState *customErrorStateForParent = new CustomErrorState(&machine); + machine.addState(customErrorStateForParent); + + CustomErrorState *customErrorStateForBrokenState = new CustomErrorState(&machine); + machine.addState(customErrorStateForBrokenState); + + QState *initialState = new QState(); + initialState->setObjectName("initialState"); + machine.addState(initialState); + machine.setInitialState(initialState); + + QState *parentOfBrokenState = new QState(); + machine.addState(parentOfBrokenState); + parentOfBrokenState->setObjectName("parentOfBrokenState"); + parentOfBrokenState->setErrorState(customErrorStateForParent); + + QState *brokenState = new QState(parentOfBrokenState); + brokenState->setObjectName("brokenState"); + brokenState->setErrorState(customErrorStateForBrokenState); + parentOfBrokenState->setInitialState(brokenState); + + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(customErrorStateForBrokenState)); + QCOMPARE(customErrorStateForBrokenState->error, QStateMachine::NoInitialStateError); + QCOMPARE(customErrorStateForParent->error, QStateMachine::NoError); +} + +void tst_QStateMachine::errorStateHasChildren() +{ + QStateMachine machine; + CustomErrorState *customErrorState = new CustomErrorState(&machine); + customErrorState->setObjectName("customErrorState"); + machine.addState(customErrorState); + + machine.setErrorState(customErrorState); + + QState *childOfErrorState = new QState(customErrorState); + childOfErrorState->setObjectName("childOfErrorState"); + customErrorState->setInitialState(childOfErrorState); + + QState *initialState = new QState(); + initialState->setObjectName("initialState"); + machine.addState(initialState); + machine.setInitialState(initialState); + + QState *brokenState = new QState(); + brokenState->setObjectName("brokenState"); + machine.addState(brokenState); + + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 2); + QVERIFY(machine.configuration().contains(customErrorState)); + QVERIFY(machine.configuration().contains(childOfErrorState)); +} + + +void tst_QStateMachine::errorStateHasErrors() +{ + QStateMachine machine; + CustomErrorState *customErrorState = new CustomErrorState(&machine); + customErrorState->setObjectName("customErrorState"); + machine.addState(customErrorState); + + QAbstractState *oldErrorState = machine.errorState(); + machine.setErrorState(customErrorState); + + QState *childOfErrorState = new QState(customErrorState); + childOfErrorState->setObjectName("childOfErrorState"); + + QState *initialState = new QState(); + initialState->setObjectName("initialState"); + machine.addState(initialState); + machine.setInitialState(initialState); + + QState *brokenState = new QState(); + brokenState->setObjectName("brokenState"); + machine.addState(brokenState); + + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'customErrorState'"); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(oldErrorState)); // Fall back to default + QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); + QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'customErrorState'")); +} + +void tst_QStateMachine::errorStateIsRootState() +{ + QStateMachine machine; + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::setErrorState: root state cannot be error state"); + machine.setErrorState(machine.rootState()); + + QState *initialState = new QState(); + initialState->setObjectName("initialState"); + machine.addState(initialState); + machine.setInitialState(initialState); + + QState *brokenState = new QState(); + brokenState->setObjectName("brokenState"); + machine.addState(brokenState); + + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'brokenState'"); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(machine.errorState())); +} + +void tst_QStateMachine::errorStateEntersParentFirst() +{ + QStateMachine machine; + + QObject *entryController = new QObject(&machine); + entryController->setObjectName("entryController"); + entryController->setProperty("greatGrandParentEntered", false); + entryController->setProperty("grandParentEntered", false); + entryController->setProperty("parentEntered", false); + entryController->setProperty("errorStateEntered", false); + + QState *greatGrandParent = new QState(); + greatGrandParent->setObjectName("greatGrandParent"); + greatGrandParent->assignProperty(entryController, "greatGrandParentEntered", true); + machine.addState(greatGrandParent); + machine.setInitialState(greatGrandParent); + + QState *grandParent = new QState(greatGrandParent); + grandParent->setObjectName("grandParent"); + grandParent->assignProperty(entryController, "grandParentEntered", true); + + QState *parent = new QState(grandParent); + parent->setObjectName("parent"); + parent->assignProperty(entryController, "parentEntered", true); + + QState *errorState = new QState(parent); + errorState->setObjectName("errorState"); + errorState->assignProperty(entryController, "errorStateEntered", true); + machine.setErrorState(errorState); + + QState *initialStateOfGreatGrandParent = new QState(greatGrandParent); + initialStateOfGreatGrandParent->setObjectName("initialStateOfGreatGrandParent"); + greatGrandParent->setInitialState(initialStateOfGreatGrandParent); + + QState *brokenState = new QState(greatGrandParent); + brokenState->setObjectName("brokenState"); + + QState *childState = new QState(brokenState); + childState->setObjectName("childState"); + + initialStateOfGreatGrandParent->addTransition(new EventTransition(QEvent::User, brokenState)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), true); + QCOMPARE(entryController->property("grandParentEntered").toBool(), false); + QCOMPARE(entryController->property("parentEntered").toBool(), false); + QCOMPARE(entryController->property("errorStateEntered").toBool(), false); + QCOMPARE(machine.configuration().count(), 2); + QVERIFY(machine.configuration().contains(greatGrandParent)); + QVERIFY(machine.configuration().contains(initialStateOfGreatGrandParent)); + + entryController->setProperty("greatGrandParentEntered", false); + entryController->setProperty("grandParentEntered", false); + entryController->setProperty("parentEntered", false); + entryController->setProperty("errorStateEntered", false); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), false); + QCOMPARE(entryController->property("grandParentEntered").toBool(), true); + QCOMPARE(entryController->property("parentEntered").toBool(), true); + QCOMPARE(entryController->property("errorStateEntered").toBool(), true); + QCOMPARE(machine.configuration().count(), 4); + QVERIFY(machine.configuration().contains(greatGrandParent)); + QVERIFY(machine.configuration().contains(grandParent)); + QVERIFY(machine.configuration().contains(parent)); + QVERIFY(machine.configuration().contains(errorState)); +} + +void tst_QStateMachine::customErrorStateIsNull() +{ + QStateMachine machine; + QAbstractState *oldErrorState = machine.errorState(); + machine.rootState()->setErrorState(0); + + QState *initialState = new QState(); + machine.addState(initialState); + machine.setInitialState(initialState); + + QState *brokenState = new QState(); + machine.addState(brokenState); + + new QState(brokenState); + initialState->addTransition(new EventTransition(QEvent::User, brokenState)); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state ''"); + QCoreApplication::processEvents(); + + QCOMPARE(machine.errorState(), reinterpret_cast(0)); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(oldErrorState)); +} + +void tst_QStateMachine::clearError() +{ + QStateMachine machine; + machine.setErrorState(new QState(machine.rootState())); // avoid warnings + + QState *brokenState = new QState(machine.rootState()); + brokenState->setObjectName("brokenState"); + machine.setInitialState(brokenState); + new QState(brokenState); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); + QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'brokenState'")); + + machine.clearError(); + + QCOMPARE(machine.error(), QStateMachine::NoError); + QVERIFY(machine.errorString().isEmpty()); +} + +void tst_QStateMachine::historyStateAsInitialState() +{ + QStateMachine machine; + + QHistoryState *hs = new QHistoryState(machine.rootState()); + machine.setInitialState(hs); + + QState *s1 = new QState(machine.rootState()); + hs->setDefaultState(s1); + + QState *s2 = new QState(machine.rootState()); + + QHistoryState *s2h = new QHistoryState(s2); + s2->setInitialState(s2h); + + QState *s21 = new QState(s2); + s2h->setDefaultState(s21); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s21)); +} + +void tst_QStateMachine::historyStateHasNowhereToGo() +{ + QStateMachine machine; + + QState *initialState = new QState(machine.rootState()); + machine.setInitialState(initialState); + machine.setErrorState(new QState(machine.rootState())); // avoid warnings + + QState *brokenState = new QState(machine.rootState()); + brokenState->setObjectName("brokenState"); + brokenState->setInitialState(new QState(brokenState)); + + QHistoryState *historyState = new QHistoryState(brokenState); + historyState->setObjectName("historyState"); + initialState->addTransition(new EventTransition(QEvent::User, historyState)); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(machine.errorState())); + QCOMPARE(machine.error(), QStateMachine::NoDefaultStateInHistoryStateError); + QCOMPARE(machine.errorString(), QString::fromLatin1("Missing default state in history state 'historyState'")); +} + +void tst_QStateMachine::brokenStateIsNeverEntered() +{ + QStateMachine machine; + + QObject *entryController = new QObject(&machine); + entryController->setProperty("brokenStateEntered", false); + entryController->setProperty("childStateEntered", false); + entryController->setProperty("errorStateEntered", false); + + QState *initialState = new QState(machine.rootState()); + machine.setInitialState(initialState); + + QState *errorState = new QState(machine.rootState()); + errorState->assignProperty(entryController, "errorStateEntered", true); + machine.setErrorState(errorState); + + QState *brokenState = new QState(machine.rootState()); + brokenState->assignProperty(entryController, "brokenStateEntered", true); + brokenState->setObjectName("brokenState"); + + QState *childState = new QState(brokenState); + childState->assignProperty(entryController, "childStateEntered", true); + + initialState->addTransition(new EventTransition(QEvent::User, brokenState)); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(entryController->property("errorStateEntered").toBool(), true); + QCOMPARE(entryController->property("brokenStateEntered").toBool(), false); + QCOMPARE(entryController->property("childStateEntered").toBool(), false); +} + +void tst_QStateMachine::transitionToStateNotInGraph() +{ + QStateMachine machine; + + QState *initialState = new QState(machine.rootState()); + initialState->setObjectName("initialState"); + machine.setInitialState(initialState); + + QState independentState; + independentState.setObjectName("independentState"); + initialState->addTransition(&independentState); + + machine.start(); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 'initialState'"); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(qobject_cast(machine.rootState())->errorState())); +} + +void tst_QStateMachine::customErrorStateNotInGraph() +{ + QStateMachine machine; + + QState errorState; + errorState.setObjectName("errorState"); + QTest::ignoreMessage(QtWarningMsg, "QState::setErrorState: error state cannot belong to a different state machine"); + machine.setErrorState(&errorState); + QVERIFY(&errorState != machine.errorState()); + + QState *initialBrokenState = new QState(machine.rootState()); + initialBrokenState->setObjectName("initialBrokenState"); + machine.setInitialState(initialBrokenState); + new QState(initialBrokenState); + + machine.start(); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'initialBrokenState'"); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(machine.errorState())); +} + +void tst_QStateMachine::restoreProperties() +{ + QStateMachine machine; + QCOMPARE(machine.globalRestorePolicy(), QStateMachine::DoNotRestoreProperties); + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QObject *object = new QObject(&machine); + object->setProperty("a", 1); + object->setProperty("b", 2); + + QState *S1 = new QState(); + S1->setObjectName("S1"); + S1->assignProperty(object, "a", 3); + machine.addState(S1); + + QState *S2 = new QState(); + S2->setObjectName("S2"); + S2->assignProperty(object, "b", 5); + machine.addState(S2); + + QState *S3 = new QState(); + S3->setObjectName("S3"); + machine.addState(S3); + + QFinalState *S4 = new QFinalState(); + machine.addState(S4); + + S1->addTransition(new EventTransition(QEvent::User, S2)); + S2->addTransition(new EventTransition(QEvent::User, S3)); + S3->addTransition(S4); + + machine.setInitialState(S1); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(object->property("a").toInt(), 3); + QCOMPARE(object->property("b").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(object->property("a").toInt(), 1); + QCOMPARE(object->property("b").toInt(), 5); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(object->property("a").toInt(), 1); + QCOMPARE(object->property("b").toInt(), 2); +} + +void tst_QStateMachine::rootState() +{ + QStateMachine machine; + QVERIFY(machine.rootState() != 0); + QVERIFY(qobject_cast(machine.rootState()) != 0); + QCOMPARE(qobject_cast(machine.rootState())->parentState(), (QState*)0); + QCOMPARE(machine.rootState()->parent(), (QObject*)&machine); + QCOMPARE(machine.rootState()->machine(), &machine); + + QState *s1 = new QState(machine.rootState()); + QCOMPARE(s1->parentState(), machine.rootState()); + + QState *s2 = new QState(); + s2->setParent(&machine); + QCOMPARE(s2->parentState(), machine.rootState()); +} + +void tst_QStateMachine::addAndRemoveState() +{ + QStateMachine machine; + QStatePrivate *root_d = QStatePrivate::get(machine.rootState()); + QCOMPARE(root_d->childStates().size(), 1); // the error state + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); + + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: cannot add null state"); + machine.addState(0); + + QState *s1 = new QState(); + QCOMPARE(s1->parentState(), (QState*)0); + QCOMPARE(s1->machine(), (QStateMachine*)0); + machine.addState(s1); + QCOMPARE(s1->machine(), &machine); + QCOMPARE(s1->parentState(), machine.rootState()); + QCOMPARE(root_d->childStates().size(), 2); + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); + QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s1); + + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine"); + machine.addState(s1); + + QState *s2 = new QState(); + QCOMPARE(s2->parentState(), (QState*)0); + machine.addState(s2); + QCOMPARE(s2->parentState(), machine.rootState()); + QCOMPARE(root_d->childStates().size(), 3); + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); + QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s1); + QCOMPARE(root_d->childStates().at(2), (QAbstractState*)s2); + + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine"); + machine.addState(s2); + + machine.removeState(s1); + QCOMPARE(s1->parentState(), (QState*)0); + QCOMPARE(root_d->childStates().size(), 2); + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); + QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s2); + + machine.removeState(s2); + QCOMPARE(s2->parentState(), (QState*)0); + QCOMPARE(root_d->childStates().size(), 1); + QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); + + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::removeState: cannot remove null state"); + machine.removeState(0); + + delete s1; + delete s2; + // ### how to deal with this? + // machine.removeState(machine.errorState()); +} + +void tst_QStateMachine::stateEntryAndExit() +{ + // Two top-level states + { + QStateMachine machine; + + TestState *s1 = new TestState(machine.rootState()); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state"); + s1->addTransition((QAbstractState*)0); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add null transition"); + s1->addTransition((QAbstractTransition*)0); + QTest::ignoreMessage(QtWarningMsg, "QState::removeTransition: cannot remove null transition"); + s1->removeTransition((QAbstractTransition*)0); + + TestState *s2 = new TestState(machine.rootState()); + QFinalState *s3 = new QFinalState(machine.rootState()); + + TestTransition *t = new TestTransition(s2); + QCOMPARE(t->machine(), (QStateMachine*)0); + QCOMPARE(t->sourceState(), (QState*)0); + QCOMPARE(t->targetState(), s2); + QCOMPARE(t->targetStates().size(), 1); + QCOMPARE(t->targetStates().at(0), s2); + t->setTargetState(0); + QCOMPARE(t->targetState(), (QState*)0); + QVERIFY(t->targetStates().isEmpty()); + t->setTargetState(s2); + QCOMPARE(t->targetState(), s2); + QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::setTargetStates: target state(s) cannot be null"); + t->setTargetStates(QList() << 0); + QCOMPARE(t->targetState(), s2); + t->setTargetStates(QList() << s2); + QCOMPARE(t->targetState(), s2); + QCOMPARE(t->targetStates().size(), 1); + QCOMPARE(t->targetStates().at(0), s2); + QCOMPARE(s1->addTransition(t), (QAbstractTransition*)t); + QCOMPARE(t->sourceState(), s1); + QCOMPARE(t->machine(), &machine); + + { + QAbstractTransition *trans = s2->addTransition(s3); + QVERIFY(trans != 0); + QCOMPARE(trans->sourceState(), (QAbstractState*)s2); + QCOMPARE(trans->targetState(), (QAbstractState*)s3); + { + char warning[256]; + sprintf(warning, "QState::removeTransition: transition %p's source state (%p) is different from this state (%p)", trans, s2, s1); + QTest::ignoreMessage(QtWarningMsg, warning); + s1->removeTransition(trans); + } + s2->removeTransition(trans); + QCOMPARE(trans->sourceState(), (QAbstractState*)0); + QCOMPARE(trans->targetState(), (QAbstractState*)s3); + QCOMPARE(s2->addTransition(trans), trans); + QCOMPARE(trans->sourceState(), (QAbstractState*)s2); + } + + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s1); + QCOMPARE(machine.initialState(), (QAbstractState*)s1); + { + char warning[256]; + sprintf(warning, "QState::setInitialState: state %p is not a child of this state (%p)", machine.rootState(), machine.rootState()); + QTest::ignoreMessage(QtWarningMsg, warning); + machine.setInitialState(machine.rootState()); + QCOMPARE(machine.initialState(), (QAbstractState*)s1); + } + QVERIFY(machine.configuration().isEmpty()); + globalTick = 0; + QVERIFY(!machine.isRunning()); + machine.start(); + + QTRY_COMPARE(startedSpy.count(), 1); + QTRY_COMPARE(finishedSpy.count(), 1); + QTRY_COMPARE(stoppedSpy.count(), 0); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s3)); + + // s1 is entered + QCOMPARE(s1->events.count(), 2); + QCOMPARE(s1->events.at(0).first, 0); + QCOMPARE(s1->events.at(0).second, TestState::Entry); + // s1 is exited + QCOMPARE(s1->events.at(1).first, 1); + QCOMPARE(s1->events.at(1).second, TestState::Exit); + // t is triggered + QCOMPARE(t->triggers.count(), 1); + QCOMPARE(t->triggers.at(0), 2); + // s2 is entered + QCOMPARE(s2->events.count(), 2); + QCOMPARE(s2->events.at(0).first, 3); + QCOMPARE(s2->events.at(0).second, TestState::Entry); + // s2 is exited + QCOMPARE(s2->events.at(1).first, 4); + QCOMPARE(s2->events.at(1).second, TestState::Exit); + } + // Two top-level states, one has two child states + { + QStateMachine machine; + + TestState *s1 = new TestState(machine.rootState()); + TestState *s11 = new TestState(s1); + TestState *s12 = new TestState(s1); + TestState *s2 = new TestState(machine.rootState()); + QFinalState *s3 = new QFinalState(machine.rootState()); + s1->setInitialState(s11); + TestTransition *t1 = new TestTransition(s12); + s11->addTransition(t1); + TestTransition *t2 = new TestTransition(s2); + s12->addTransition(t2); + s2->addTransition(s3); + + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s1); + globalTick = 0; + machine.start(); + + QTRY_COMPARE(startedSpy.count(), 1); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s3)); + + // s1 is entered + QCOMPARE(s1->events.count(), 2); + QCOMPARE(s1->events.at(0).first, 0); + QCOMPARE(s1->events.at(0).second, TestState::Entry); + // s11 is entered + QCOMPARE(s11->events.count(), 2); + QCOMPARE(s11->events.at(0).first, 1); + QCOMPARE(s11->events.at(0).second, TestState::Entry); + // s11 is exited + QCOMPARE(s11->events.at(1).first, 2); + QCOMPARE(s11->events.at(1).second, TestState::Exit); + // t1 is triggered + QCOMPARE(t1->triggers.count(), 1); + QCOMPARE(t1->triggers.at(0), 3); + // s12 is entered + QCOMPARE(s12->events.count(), 2); + QCOMPARE(s12->events.at(0).first, 4); + QCOMPARE(s12->events.at(0).second, TestState::Entry); + // s12 is exited + QCOMPARE(s12->events.at(1).first, 5); + QCOMPARE(s12->events.at(1).second, TestState::Exit); + // s1 is exited + QCOMPARE(s1->events.at(1).first, 6); + QCOMPARE(s1->events.at(1).second, TestState::Exit); + // t2 is triggered + QCOMPARE(t2->triggers.count(), 1); + QCOMPARE(t2->triggers.at(0), 7); + // s2 is entered + QCOMPARE(s2->events.count(), 2); + QCOMPARE(s2->events.at(0).first, 8); + QCOMPARE(s2->events.at(0).second, TestState::Entry); + // s2 is exited + QCOMPARE(s2->events.at(1).first, 9); + QCOMPARE(s2->events.at(1).second, TestState::Exit); + } +} + +void tst_QStateMachine::assignProperty() +{ + QStateMachine machine; + QState *s1 = new QState(machine.rootState()); + + QTest::ignoreMessage(QtWarningMsg, "QState::assignProperty: cannot assign property 'foo' of null object"); + s1->assignProperty(0, "foo", QVariant()); + + s1->assignProperty(s1, "objectName", "s1"); + QFinalState *s2 = new QFinalState(machine.rootState()); + s1->addTransition(s2); + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(s1->objectName(), QString::fromLatin1("s1")); + + s1->assignProperty(s1, "objectName", "foo"); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(s1->objectName(), QString::fromLatin1("foo")); + + s1->assignProperty(s1, "noSuchProperty", 123); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(s1->objectName(), QString::fromLatin1("foo")); + QCOMPARE(s1->dynamicPropertyNames().size(), 1); + QCOMPARE(s1->dynamicPropertyNames().at(0), QByteArray("noSuchProperty")); + + QSignalSpy polishedSpy(s1, SIGNAL(polished())); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(polishedSpy.count(), 1); +} + +void tst_QStateMachine::assignPropertyWithAnimation() +{ + // Single animation + { + QStateMachine machine; + QVERIFY(machine.animationsEnabled()); + machine.setAnimationsEnabled(false); + QVERIFY(!machine.animationsEnabled()); + machine.setAnimationsEnabled(true); + QVERIFY(machine.animationsEnabled()); + QObject obj; + obj.setProperty("foo", 321); + obj.setProperty("bar", 654); + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(&obj, "foo", 123); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(&obj, "foo", 456); + s2->assignProperty(&obj, "bar", 789); + QAbstractTransition *trans = s1->addTransition(s2); + QVERIFY(trans->animations().isEmpty()); + QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::addAnimation: cannot add null animation"); + trans->addAnimation(0); + QPropertyAnimation anim(&obj, "foo"); + anim.setDuration(250); + trans->addAnimation(&anim); + QCOMPARE(trans->animations().size(), 1); + QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim); + QCOMPARE(anim.parent(), (QObject*)0); + QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::removeAnimation: cannot remove null animation"); + trans->removeAnimation(0); + trans->removeAnimation(&anim); + QVERIFY(trans->animations().isEmpty()); + trans->addAnimation(&anim); + QCOMPARE(trans->animations().size(), 1); + QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim); + QFinalState *s3 = new QFinalState(machine.rootState()); + s2->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(obj.property("foo").toInt(), 456); + QCOMPARE(obj.property("bar").toInt(), 789); + } + // Two animations + { + QStateMachine machine; + QObject obj; + obj.setProperty("foo", 321); + obj.setProperty("bar", 654); + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(&obj, "foo", 123); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(&obj, "foo", 456); + s2->assignProperty(&obj, "bar", 789); + QAbstractTransition *trans = s1->addTransition(s2); + QPropertyAnimation anim(&obj, "foo"); + anim.setDuration(150); + trans->addAnimation(&anim); + QPropertyAnimation anim2(&obj, "bar"); + anim2.setDuration(150); + trans->addAnimation(&anim2); + QFinalState *s3 = new QFinalState(machine.rootState()); + s2->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(obj.property("foo").toInt(), 456); + QCOMPARE(obj.property("bar").toInt(), 789); + } + // Animation group + { + QStateMachine machine; + QObject obj; + obj.setProperty("foo", 321); + obj.setProperty("bar", 654); + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(&obj, "foo", 123); + s1->assignProperty(&obj, "bar", 321); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(&obj, "foo", 456); + s2->assignProperty(&obj, "bar", 654); + s2->assignProperty(&obj, "baz", 789); + QAbstractTransition *trans = s1->addTransition(s2); + QSequentialAnimationGroup group; + group.addAnimation(new QPropertyAnimation(&obj, "foo")); + group.addAnimation(new QPropertyAnimation(&obj, "bar")); + trans->addAnimation(&group); + QFinalState *s3 = new QFinalState(machine.rootState()); + s2->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(obj.property("foo").toInt(), 456); + QCOMPARE(obj.property("bar").toInt(), 654); + QCOMPARE(obj.property("baz").toInt(), 789); + } + // Nested states + { + QStateMachine machine; + QObject obj; + obj.setProperty("foo", 321); + obj.setProperty("bar", 654); + QState *s1 = new QState(machine.rootState()); + QCOMPARE(s1->childMode(), QState::ExclusiveStates); + s1->setChildMode(QState::ParallelStates); + QCOMPARE(s1->childMode(), QState::ParallelStates); + s1->setChildMode(QState::ExclusiveStates); + QCOMPARE(s1->childMode(), QState::ExclusiveStates); + QCOMPARE(s1->initialState(), (QAbstractState*)0); + s1->setObjectName("s1"); + s1->assignProperty(&obj, "foo", 123); + s1->assignProperty(&obj, "bar", 456); + QState *s2 = new QState(machine.rootState()); + s2->setObjectName("s2"); + s2->assignProperty(&obj, "foo", 321); + QState *s21 = new QState(s2); + s21->setObjectName("s21"); + s21->assignProperty(&obj, "bar", 654); + QState *s22 = new QState(s2); + s22->setObjectName("s22"); + s22->assignProperty(&obj, "bar", 789); + s2->setInitialState(s21); + QCOMPARE(s2->initialState(), (QAbstractState*)s21); + + QAbstractTransition *trans = s1->addTransition(s2); + QPropertyAnimation anim(&obj, "foo"); + anim.setDuration(500); + trans->addAnimation(&anim); + QPropertyAnimation anim2(&obj, "bar"); + anim2.setDuration(250); + trans->addAnimation(&anim2); + + s21->addTransition(s21, SIGNAL(polished()), s22); + + QFinalState *s3 = new QFinalState(machine.rootState()); + s22->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(obj.property("foo").toInt(), 321); + QCOMPARE(obj.property("bar").toInt(), 789); + } +} + +struct StringEvent : public QEvent +{ +public: + StringEvent(const QString &val) + : QEvent(QEvent::Type(QEvent::User+2)), + value(val) {} + + QString value; +}; + +class StringTransition : public QAbstractTransition +{ +public: + StringTransition(const QString &value, QAbstractState *target) + : QAbstractTransition(QList() << target), m_value(value) {} + +protected: + virtual bool eventTest(QEvent *e) + { + if (e->type() != QEvent::Type(QEvent::User+2)) + return false; + StringEvent *se = static_cast(e); + return (m_value == se->value) && (!m_cond.isValid() || (m_cond.indexIn(m_value) != -1)); + } + virtual void onTransition(QEvent *) {} + +private: + QString m_value; + QRegExp m_cond; +}; + +class StringEventPoster : public QState +{ +public: + StringEventPoster(QStateMachine *machine, const QString &value, QState *parent = 0) + : QState(parent), m_machine(machine), m_value(value), m_delay(0) {} + + void setString(const QString &value) + { m_value = value; } + void setDelay(int delay) + { m_delay = delay; } + +protected: + virtual void onEntry(QEvent *) + { + m_machine->postEvent(new StringEvent(m_value), m_delay); + } + virtual void onExit(QEvent *) {} + +private: + QStateMachine *m_machine; + QString m_value; + int m_delay; +}; + +void tst_QStateMachine::postEvent() +{ + for (int x = 0; x < 2; ++x) { + QStateMachine machine; + { + QEvent e(QEvent::None); + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::postEvent: cannot post event when the state machine is not running"); + machine.postEvent(&e); + } + StringEventPoster *s1 = new StringEventPoster(&machine, "a"); + if (x == 1) + s1->setDelay(100); + QFinalState *s2 = new QFinalState; + s1->addTransition(new StringTransition("a", s2)); + machine.addState(s1); + machine.addState(s2); + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + + s1->setString("b"); + QFinalState *s3 = new QFinalState(); + machine.addState(s3); + s1->addTransition(new StringTransition("b", s3)); + finishedSpy.clear(); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s3)); + } +} + +void tst_QStateMachine::stateFinished() +{ + QStateMachine machine; + QState *s1 = new QState(machine.rootState()); + QState *s1_1 = new QState(s1); + QFinalState *s1_2 = new QFinalState(s1); + s1_1->addTransition(s1_2); + s1->setInitialState(s1_1); + QFinalState *s2 = new QFinalState(machine.rootState()); + s1->addTransition(s1, SIGNAL(finished()), s2); + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); +} + +void tst_QStateMachine::parallelStates() +{ + QStateMachine machine; + + QState *s1 = new QState(QState::ParallelStates); + QCOMPARE(s1->childMode(), QState::ParallelStates); + QState *s1_1 = new QState(s1); + QState *s1_1_1 = new QState(s1_1); + QFinalState *s1_1_f = new QFinalState(s1_1); + s1_1_1->addTransition(s1_1_f); + s1_1->setInitialState(s1_1_1); + QState *s1_2 = new QState(s1); + QState *s1_2_1 = new QState(s1_2); + QFinalState *s1_2_f = new QFinalState(s1_2); + s1_2_1->addTransition(s1_2_f); + s1_2->setInitialState(s1_2_1); + { + char warning[256]; + sprintf(warning, "QState::setInitialState: ignoring attempt to set initial state of parallel state group %p", s1); + QTest::ignoreMessage(QtWarningMsg, warning); + s1->setInitialState(0); + } + machine.addState(s1); + + QFinalState *s2 = new QFinalState(); + machine.addState(s2); + + s1->addTransition(s1, SIGNAL(finished()), s2); + + machine.setInitialState(s1); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); +} + +void tst_QStateMachine::allSourceToTargetConfigurations() +{ + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + s0->setObjectName("s0"); + QState *s1 = new QState(s0); + s1->setObjectName("s1"); + QState *s11 = new QState(s1); + s11->setObjectName("s11"); + QState *s2 = new QState(s0); + s2->setObjectName("s2"); + QState *s21 = new QState(s2); + s21->setObjectName("s21"); + QState *s211 = new QState(s21); + s211->setObjectName("s211"); + QFinalState *f = new QFinalState(machine.rootState()); + f->setObjectName("f"); + + s0->setInitialState(s1); + s1->setInitialState(s11); + s2->setInitialState(s21); + s21->setInitialState(s211); + + s11->addTransition(new StringTransition("g", s211)); + s1->addTransition(new StringTransition("a", s1)); + s1->addTransition(new StringTransition("b", s11)); + s1->addTransition(new StringTransition("c", s2)); + s1->addTransition(new StringTransition("d", s0)); + s1->addTransition(new StringTransition("f", s211)); + s211->addTransition(new StringTransition("d", s21)); + s211->addTransition(new StringTransition("g", s0)); + s211->addTransition(new StringTransition("h", f)); + s21->addTransition(new StringTransition("b", s211)); + s2->addTransition(new StringTransition("c", s1)); + s2->addTransition(new StringTransition("f", s11)); + s0->addTransition(new StringTransition("e", s211)); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new StringEvent("a")); + QCoreApplication::processEvents(); + machine.postEvent(new StringEvent("b")); + QCoreApplication::processEvents(); + machine.postEvent(new StringEvent("c")); + QCoreApplication::processEvents(); + machine.postEvent(new StringEvent("d")); + QCoreApplication::processEvents(); + machine.postEvent(new StringEvent("e")); + QCoreApplication::processEvents(); + machine.postEvent(new StringEvent("f")); + QCoreApplication::processEvents(); + machine.postEvent(new StringEvent("g")); + QCoreApplication::processEvents(); + machine.postEvent(new StringEvent("h")); + QCoreApplication::processEvents(); + + QTRY_COMPARE(finishedSpy.count(), 1); +} + +class SignalEmitter : public QObject +{ +Q_OBJECT + public: + SignalEmitter(QObject *parent = 0) + : QObject(parent) {} + void emitSignalWithNoArg() + { emit signalWithNoArg(); } + void emitSignalWithIntArg(int arg) + { emit signalWithIntArg(arg); } + void emitSignalWithStringArg(const QString &arg) + { emit signalWithStringArg(arg); } +Q_SIGNALS: + void signalWithNoArg(); + void signalWithIntArg(int); + void signalWithStringArg(const QString &); +}; + +class TestSignalTransition : public QSignalTransition +{ +public: + TestSignalTransition(QState *sourceState = 0) + : QSignalTransition(sourceState) {} + TestSignalTransition(QObject *sender, const char *signal, + QAbstractState *target) + : QSignalTransition(sender, signal, QList() << target) {} + QVariantList argumentsReceived() const { + return m_args; + } +protected: + bool eventTest(QEvent *e) { + if (!QSignalTransition::eventTest(e)) + return false; + QSignalEvent *se = static_cast(e); + const_cast(this)->m_args = se->arguments(); + return true; + } +private: + QVariantList m_args; +}; + +void tst_QStateMachine::signalTransitions() +{ + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: sender cannot be null"); + QCOMPARE(s0->addTransition(0, SIGNAL(noSuchSignal()), 0), (QObject*)0); + + SignalEmitter emitter; + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: signal cannot be null"); + QCOMPARE(s0->addTransition(&emitter, 0, 0), (QObject*)0); + + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state"); + QCOMPARE(s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), 0), (QObject*)0); + + QFinalState *s1 = new QFinalState(machine.rootState()); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: no such signal SignalEmitter::noSuchSignal()"); + QCOMPARE(s0->addTransition(&emitter, SIGNAL(noSuchSignal()), s1), (QObject*)0); + + { + QSignalTransition *trans = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); + QVERIFY(trans != 0); + QCOMPARE(trans->sourceState(), s0); + QCOMPARE(trans->targetState(), (QAbstractState*)s1); + QCOMPARE(trans->senderObject(), (QObject*)&emitter); + QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); + } + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + emitter.emitSignalWithNoArg(); + + QTRY_COMPARE(finishedSpy.count(), 1); + + emitter.emitSignalWithNoArg(); + } + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + SignalEmitter emitter; + TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithIntArg(int)), s1); + s0->addTransition(trans); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + emitter.emitSignalWithIntArg(123); + + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(trans->argumentsReceived().size(), 1); + QCOMPARE(trans->argumentsReceived().at(0).toInt(), 123); + } + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + SignalEmitter emitter; + TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s1); + s0->addTransition(trans); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + QString testString = QString::fromLatin1("hello"); + emitter.emitSignalWithStringArg(testString); + + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(trans->argumentsReceived().size(), 1); + QCOMPARE(trans->argumentsReceived().at(0).toString(), testString); + } + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + + TestSignalTransition *trans = new TestSignalTransition(); + QCOMPARE(trans->senderObject(), (QObject*)0); + QCOMPARE(trans->signal(), QByteArray()); + + SignalEmitter emitter; + trans->setSenderObject(&emitter); + QCOMPARE(trans->senderObject(), (QObject*)&emitter); + trans->setSignal(SIGNAL(signalWithNoArg())); + QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); + trans->setTargetState(s1); + s0->addTransition(trans); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + emitter.emitSignalWithNoArg(); + + QTRY_COMPARE(finishedSpy.count(), 1); + } + // Multiple transitions for same (object,signal) + { + QStateMachine machine; + SignalEmitter emitter; + QState *s0 = new QState(machine.rootState()); + QState *s1 = new QState(machine.rootState()); + QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); + QSignalTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s0); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s0)); + + emitter.emitSignalWithNoArg(); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + s0->removeTransition(t0); + emitter.emitSignalWithNoArg(); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s0)); + + emitter.emitSignalWithNoArg(); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s0)); + + s1->removeTransition(t1); + emitter.emitSignalWithNoArg(); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s0)); + + s0->addTransition(t0); + s1->addTransition(t1); + emitter.emitSignalWithNoArg(); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + } +} + +void tst_QStateMachine::eventTransitions() +{ + QPushButton button; + for (int x = 0; x < 2; ++x) { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + + QMouseEventTransition *trans; + if (x == 0) { + trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, Qt::LeftButton); + QCOMPARE(trans->targetState(), (QAbstractState*)0); + trans->setTargetState(s1); + } else { + trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, + Qt::LeftButton, QList() << s1); + } + QCOMPARE(trans->eventType(), QEvent::MouseButtonPress); + QCOMPARE(trans->button(), Qt::LeftButton); + QCOMPARE(trans->targetState(), (QAbstractState*)s1); + s0->addTransition(trans); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + QTest::mousePress(&button, Qt::LeftButton); + QTRY_COMPARE(finishedSpy.count(), 1); + + QTest::mousePress(&button, Qt::LeftButton); + + trans->setEventType(QEvent::MouseButtonRelease); + QCOMPARE(trans->eventType(), QEvent::MouseButtonRelease); + machine.start(); + QCoreApplication::processEvents(); + QTest::mouseRelease(&button, Qt::LeftButton); + QTRY_COMPARE(finishedSpy.count(), 2); + } + for (int x = 0; x < 3; ++x) { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + + QEventTransition *trans; + if (x == 0) { + trans = new QEventTransition(); + QCOMPARE(trans->eventObject(), (QObject*)0); + QCOMPARE(trans->eventType(), QEvent::None); + trans->setEventObject(&button); + trans->setEventType(QEvent::MouseButtonPress); + trans->setTargetState(s1); + } else if (x == 1) { + trans = new QEventTransition(&button, QEvent::MouseButtonPress); + trans->setTargetState(s1); + } else { + trans = new QEventTransition(&button, QEvent::MouseButtonPress, + QList() << s1); + } + QCOMPARE(trans->eventObject(), (QObject*)&button); + QCOMPARE(trans->eventType(), QEvent::MouseButtonPress); + QCOMPARE(trans->targetState(), (QAbstractState*)s1); + s0->addTransition(trans); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + QTest::mousePress(&button, Qt::LeftButton); + QCoreApplication::processEvents(); + + QTRY_COMPARE(finishedSpy.count(), 1); + } + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + + QMouseEventTransition *trans = new QMouseEventTransition(); + QCOMPARE(trans->eventObject(), (QObject*)0); + QCOMPARE(trans->eventType(), QEvent::None); + QCOMPARE(trans->button(), Qt::NoButton); + trans->setEventObject(&button); + trans->setEventType(QEvent::MouseButtonPress); + trans->setButton(Qt::LeftButton); + trans->setTargetState(s1); + s0->addTransition(trans); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + QTest::mousePress(&button, Qt::LeftButton); + QCoreApplication::processEvents(); + + QTRY_COMPARE(finishedSpy.count(), 1); + } + + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + + QKeyEventTransition *trans = new QKeyEventTransition(&button, QEvent::KeyPress, Qt::Key_A); + QCOMPARE(trans->eventType(), QEvent::KeyPress); + QCOMPARE(trans->key(), (int)Qt::Key_A); + trans->setTargetState(s1); + s0->addTransition(trans); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + QTest::keyPress(&button, Qt::Key_A); + QCoreApplication::processEvents(); + + QTRY_COMPARE(finishedSpy.count(), 1); + } + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + + QKeyEventTransition *trans = new QKeyEventTransition(); + QCOMPARE(trans->eventObject(), (QObject*)0); + QCOMPARE(trans->eventType(), QEvent::None); + QCOMPARE(trans->key(), 0); + trans->setEventObject(&button); + trans->setEventType(QEvent::KeyPress); + trans->setKey(Qt::Key_A); + trans->setTargetState(s1); + s0->addTransition(trans); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + + QTest::keyPress(&button, Qt::Key_A); + QCoreApplication::processEvents(); + + QTRY_COMPARE(finishedSpy.count(), 1); + } + // Multiple transitions for same (object,event) + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QState *s1 = new QState(machine.rootState()); + QEventTransition *t0 = new QEventTransition(&button, QEvent::MouseButtonPress); + t0->setTargetState(s1); + s0->addTransition(t0); + QEventTransition *t1 = new QEventTransition(&button, QEvent::MouseButtonPress); + t1->setTargetState(s0); + s1->addTransition(t1); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s0)); + + QTest::mousePress(&button, Qt::LeftButton); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + s0->removeTransition(t0); + QTest::mousePress(&button, Qt::LeftButton); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s0)); + + QTest::mousePress(&button, Qt::LeftButton); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s0)); + + s1->removeTransition(t1); + QTest::mousePress(&button, Qt::LeftButton); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s0)); + + s0->addTransition(t0); + s1->addTransition(t1); + QTest::mousePress(&button, Qt::LeftButton); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + } +} + +void tst_QStateMachine::historyStates() +{ + for (int x = 0; x < 2; ++x) { + QStateMachine machine; + QState *root = machine.rootState(); + QState *s0 = new QState(root); + QState *s00 = new QState(s0); + QState *s01 = new QState(s0); + QHistoryState *s0h; + if (x == 0) { + s0h = new QHistoryState(s0); + QCOMPARE(s0h->historyType(), QHistoryState::ShallowHistory); + s0h->setHistoryType(QHistoryState::DeepHistory); + } else { + s0h = new QHistoryState(QHistoryState::DeepHistory, s0); + } + QCOMPARE(s0h->historyType(), QHistoryState::DeepHistory); + s0h->setHistoryType(QHistoryState::ShallowHistory); + QCOMPARE(s0h->historyType(), QHistoryState::ShallowHistory); + QCOMPARE(s0h->defaultState(), (QAbstractState*)0); + s0h->setDefaultState(s00); + QCOMPARE(s0h->defaultState(), (QAbstractState*)s00); + char warning[256]; + sprintf(warning, "QHistoryState::setDefaultState: state %p does not belong to this history state's group (%p)", s0, s0); + QTest::ignoreMessage(QtWarningMsg, warning); + s0h->setDefaultState(s0); + QState *s1 = new QState(root); + QFinalState *s2 = new QFinalState(root); + + s00->addTransition(new StringTransition("a", s01)); + s0->addTransition(new StringTransition("b", s1)); + s1->addTransition(new StringTransition("c", s0h)); + s0->addTransition(new StringTransition("d", s2)); + + root->setInitialState(s0); + s0->setInitialState(s00); + + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s0)); + QVERIFY(machine.configuration().contains(s00)); + + machine.postEvent(new StringEvent("a")); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s0)); + QVERIFY(machine.configuration().contains(s01)); + + machine.postEvent(new StringEvent("b")); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.postEvent(new StringEvent("c")); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s0)); + QVERIFY(machine.configuration().contains(s01)); + + machine.postEvent(new StringEvent("d")); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + + QTRY_COMPARE(finishedSpy.count(), 1); + } +} + +void tst_QStateMachine::startAndStop() +{ + QStateMachine machine; + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + QVERIFY(!machine.isRunning()); + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start."); + machine.start(); + QCOMPARE(startedSpy.count(), 0); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QVERIFY(!machine.isRunning()); + machine.stop(); + QCOMPARE(startedSpy.count(), 0); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + machine.start(); + QTRY_COMPARE(machine.isRunning(), true); + QTRY_COMPARE(startedSpy.count(), 1); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.stop(); + QTRY_COMPARE(machine.isRunning(), false); + QTRY_COMPARE(stoppedSpy.count(), 1); + QCOMPARE(startedSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + + QCOMPARE(machine.configuration().count(), 1); + QVERIFY(machine.configuration().contains(s1)); +} + +void tst_QStateMachine::targetStateWithNoParent() +{ + QStateMachine machine; + QState *s1 = new QState(machine.rootState()); + s1->setObjectName("s1"); + QState s2; + s1->addTransition(&s2); + machine.setInitialState(s1); + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 's1'"); + QTRY_COMPARE(machine.isRunning(), true); + QTRY_COMPARE(startedSpy.count(), 1); + QCOMPARE(stoppedSpy.count(), 0); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(machine.errorState())); + QCOMPARE(machine.error(), QStateMachine::NoCommonAncestorForTransitionError); +} + +void tst_QStateMachine::targetStateDeleted() +{ + QStateMachine machine; + QState *s1 = new QState(machine.rootState()); + s1->setObjectName("s1"); + QState *s2 = new QState(machine.rootState()); + QAbstractTransition *trans = s1->addTransition(s2); + delete s2; + QCOMPARE(trans->targetState(), (QAbstractState*)0); + QVERIFY(trans->targetStates().isEmpty()); +} + +void tst_QStateMachine::defaultGlobalRestorePolicy() +{ + QStateMachine machine; + + QObject *propertyHolder = new QObject(&machine); + propertyHolder->setProperty("a", 1); + propertyHolder->setProperty("b", 2); + + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(propertyHolder, "a", 3); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(propertyHolder, "b", 4); + + QState *s3 = new QState(machine.rootState()); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s2->addTransition(new EventTransition(QEvent::User, s3)); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 4); +} + +/* +void tst_QStateMachine::restorePolicyNotInherited() +{ + QStateMachine machine; + + QObject *propertyHolder = new QObject(); + propertyHolder->setProperty("a", 1); + propertyHolder->setProperty("b", 2); + + QState *parentState = new QState(machine.rootState()); + parentState->setObjectName("parentState"); + parentState->setRestorePolicy(QState::RestoreProperties); + + QState *s1 = new QState(parentState); + s1->setObjectName("s1"); + s1->assignProperty(propertyHolder, "a", 3); + parentState->setInitialState(s1); + + QState *s2 = new QState(parentState); + s2->setObjectName("s2"); + s2->assignProperty(propertyHolder, "b", 4); + + QState *s3 = new QState(parentState); + s3->setObjectName("s3"); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s2->addTransition(new EventTransition(QEvent::User, s3)); + + machine.setInitialState(parentState); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 4); + +}*/ + +void tst_QStateMachine::globalRestorePolicySetToDoNotRestore() +{ + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::DoNotRestoreProperties); + + QObject *propertyHolder = new QObject(&machine); + propertyHolder->setProperty("a", 1); + propertyHolder->setProperty("b", 2); + + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(propertyHolder, "a", 3); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(propertyHolder, "b", 4); + + QState *s3 = new QState(machine.rootState()); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s2->addTransition(new EventTransition(QEvent::User, s3)); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 4); +} + +/* +void tst_QStateMachine::setRestorePolicyToDoNotRestore() +{ + QObject *object = new QObject(); + object->setProperty("a", 1); + object->setProperty("b", 2); + + QStateMachine machine; + + QState *S1 = new QState(); + S1->setObjectName("S1"); + S1->assignProperty(object, "a", 3); + S1->setRestorePolicy(QState::DoNotRestoreProperties); + machine.addState(S1); + + QState *S2 = new QState(); + S2->setObjectName("S2"); + S2->assignProperty(object, "b", 5); + S2->setRestorePolicy(QState::DoNotRestoreProperties); + machine.addState(S2); + + QState *S3 = new QState(); + S3->setObjectName("S3"); + S3->setRestorePolicy(QState::DoNotRestoreProperties); + machine.addState(S3); + + QFinalState *S4 = new QFinalState(); + machine.addState(S4); + + S1->addTransition(new EventTransition(QEvent::User, S2)); + S2->addTransition(new EventTransition(QEvent::User, S3)); + S3->addTransition(S4); + + machine.setInitialState(S1); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(object->property("a").toInt(), 3); + QCOMPARE(object->property("b").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(object->property("a").toInt(), 3); + QCOMPARE(object->property("b").toInt(), 5); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(object->property("a").toInt(), 3); + QCOMPARE(object->property("b").toInt(), 5); +} + +void tst_QStateMachine::setGlobalRestorePolicyToGlobalRestore() +{ + s_countWarnings = false; + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::GlobalRestorePolicy); + + QCOMPARE(machine.globalRestorePolicy(), QStateMachine::DoNotRestoreProperties); + QCOMPARE(s_msgType, QtWarningMsg); + + s_msgType = QtDebugMsg; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + machine.setGlobalRestorePolicy(QStateMachine::GlobalRestorePolicy); + + QCOMPARE(machine.globalRestorePolicy(), QStateMachine::RestoreProperties); + QCOMPARE(s_msgType, QtWarningMsg); +} + + +void tst_QStateMachine::restorePolicyOnChildState() +{ + QStateMachine machine; + + QObject *propertyHolder = new QObject(); + propertyHolder->setProperty("a", 1); + propertyHolder->setProperty("b", 2); + + QState *parentState = new QState(machine.rootState()); + parentState->setObjectName("parentState"); + + QState *s1 = new QState(parentState); + s1->setRestorePolicy(QState::RestoreProperties); + s1->setObjectName("s1"); + s1->assignProperty(propertyHolder, "a", 3); + parentState->setInitialState(s1); + + QState *s2 = new QState(parentState); + s2->setRestorePolicy(QState::RestoreProperties); + s2->setObjectName("s2"); + s2->assignProperty(propertyHolder, "b", 4); + + QState *s3 = new QState(parentState); + s3->setRestorePolicy(QState::RestoreProperties); + s3->setObjectName("s3"); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s2->addTransition(new EventTransition(QEvent::User, s3)); + + machine.setInitialState(parentState); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 1); + QCOMPARE(propertyHolder->property("b").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 1); + QCOMPARE(propertyHolder->property("b").toInt(), 2); +} +*/ + +void tst_QStateMachine::globalRestorePolicySetToRestore() +{ + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QObject *propertyHolder = new QObject(&machine); + propertyHolder->setProperty("a", 1); + propertyHolder->setProperty("b", 2); + + QState *s1 = new QState(machine.rootState()); + s1->assignProperty(propertyHolder, "a", 3); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(propertyHolder, "b", 4); + + QState *s3 = new QState(machine.rootState()); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s2->addTransition(new EventTransition(QEvent::User, s3)); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 3); + QCOMPARE(propertyHolder->property("b").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 1); + QCOMPARE(propertyHolder->property("b").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("a").toInt(), 1); + QCOMPARE(propertyHolder->property("b").toInt(), 2); +} + +/* +void tst_QStateMachine::mixedRestoreProperties() +{ + QStateMachine machine; + + QObject *propertyHolder = new QObject(); + propertyHolder->setProperty("a", 1); + + QState *s1 = new QState(machine.rootState()); + s1->setRestorePolicy(QState::RestoreProperties); + s1->assignProperty(propertyHolder, "a", 3); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(propertyHolder, "a", 4); + + QState *s3 = new QState(machine.rootState()); + + QState *s4 = new QState(machine.rootState()); + s4->assignProperty(propertyHolder, "a", 5); + + QState *s5 = new QState(machine.rootState()); + s5->setRestorePolicy(QState::RestoreProperties); + s5->assignProperty(propertyHolder, "a", 6); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s2->addTransition(new EventTransition(QEvent::User, s3)); + s3->addTransition(new EventTransition(QEvent::User, s4)); + s4->addTransition(new EventTransition(QEvent::User, s5)); + s5->addTransition(new EventTransition(QEvent::User, s3)); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + // Enter s1, save current + QCOMPARE(propertyHolder->property("a").toInt(), 3); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + // Enter s2, restorePolicy == DoNotRestore, so restore all properties + QCOMPARE(propertyHolder->property("a").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + // Enter s3 + QCOMPARE(propertyHolder->property("a").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + // Enter s4 + QCOMPARE(propertyHolder->property("a").toInt(), 5); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + // Enter s5, save current + QCOMPARE(propertyHolder->property("a").toInt(), 6); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + // Enter s3, restore + QCOMPARE(propertyHolder->property("a").toInt(), 5); +} +*/ + +void tst_QStateMachine::transitionWithParent() +{ + QStateMachine machine; + QState *s1 = new QState(machine.rootState()); + QState *s2 = new QState(machine.rootState()); + EventTransition *trans = new EventTransition(QEvent::User, s2, s1); + QCOMPARE(trans->sourceState(), s1); + QCOMPARE(trans->targetState(), (QAbstractState*)s2); + QCOMPARE(trans->targetStates().size(), 1); + QCOMPARE(trans->targetStates().at(0), (QAbstractState*)s2); +} + +void tst_QStateMachine::simpleAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(&machine); + object->setProperty("fooBar", 1.0); + + QState *s1 = new QState(machine.rootState()); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "fooBar", 2.0); + + EventTransition *et = new EventTransition(QEvent::User, s2); + QPropertyAnimation *animation = new QPropertyAnimation(object, "fooBar", s2); + et->addAnimation(animation); + s1->addTransition(et); + + QState *s3 = new QState(machine.rootState()); + s2->addTransition(animation, SIGNAL(finished()), s3); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("fooBar").toDouble(), 2.0); +} + +class SlotCalledCounter: public QObject +{ + Q_OBJECT +public: + SlotCalledCounter() : counter(0) {} + + int counter; + +public slots: + void slot() { counter++; } +}; + +void tst_QStateMachine::twoAnimations() +{ + QStateMachine machine; + + QObject *object = new QObject(&machine); + object->setProperty("foo", 1.0); + object->setProperty("bar", 3.0); + + QState *s1 = new QState(machine.rootState()); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + s2->assignProperty(object, "bar", 10.0); + + QPropertyAnimation *animationFoo = new QPropertyAnimation(object, "foo", s2); + QPropertyAnimation *animationBar = new QPropertyAnimation(object, "bar", s2); + animationBar->setDuration(900); + + SlotCalledCounter counter; + connect(animationFoo, SIGNAL(finished()), &counter, SLOT(slot())); + connect(animationBar, SIGNAL(finished()), &counter, SLOT(slot())); + + EventTransition *et = new EventTransition(QEvent::User, s2); + et->addAnimation(animationFoo); + et->addAnimation(animationBar); + s1->addTransition(et); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + s2->addTransition(s2, SIGNAL(polished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); + QCOMPARE(object->property("bar").toDouble(), 10.0); + + QCOMPARE(counter.counter, 2); +} + +void tst_QStateMachine::twoAnimatedTransitions() +{ + QStateMachine machine; + + QObject *object = new QObject(&machine); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 5.0); + QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); + s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + s2->addTransition(fooAnimation, SIGNAL(finished()), s3); + + QState *s4 = new QState(machine.rootState()); + s4->assignProperty(object, "foo", 2.0); + QPropertyAnimation *fooAnimation2 = new QPropertyAnimation(object, "foo", s4); + s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation2); + + QState *s5 = new QState(machine.rootState()); + QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit())); + s4->addTransition(fooAnimation2, SIGNAL(finished()), s5); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 5.0); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s5)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::playAnimationTwice() +{ + QStateMachine machine; + + QObject *object = new QObject(&machine); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 5.0); + QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); + s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + s2->addTransition(fooAnimation, SIGNAL(finished()), s3); + + QState *s4 = new QState(machine.rootState()); + s4->assignProperty(object, "foo", 2.0); + s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation); + + QState *s5 = new QState(machine.rootState()); + QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit())); + s4->addTransition(fooAnimation, SIGNAL(finished()), s5); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 5.0); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s5)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::nestedTargetStateForAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(&machine); + object->setProperty("foo", 1.0); + object->setProperty("bar", 3.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + QState *s2 = new QState(machine.rootState()); + + s2->assignProperty(object, "foo", 2.0); + + QState *s2Child = new QState(s2); + s2Child->assignProperty(object, "bar", 10.0); + s2->setInitialState(s2Child); + + QState *s2Child2 = new QState(s2); + s2Child2->assignProperty(object, "bar", 11.0); + QAbstractTransition *at = s2Child->addTransition(new EventTransition(QEvent::User, s2Child2)); + + QPropertyAnimation *animation = new QPropertyAnimation(object, "bar", s2); + animation->setDuration(2000); + connect(animation, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(animation); + + at = s1->addTransition(new EventTransition(QEvent::User, s2)); + + animation = new QPropertyAnimation(object, "foo", s2); + connect(animation, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(animation); + + animation = new QPropertyAnimation(object, "bar", s2); + connect(animation, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(animation); + + QState *s3 = new QState(machine.rootState()); + s2->addTransition(s2Child, SIGNAL(polished()), s3); + + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + machine.postEvent(new QEvent(QEvent::User)); + + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); + QCOMPARE(object->property("bar").toDouble(), 10.0); + QCOMPARE(counter.counter, 2); +} + +void tst_QStateMachine::animatedGlobalRestoreProperty() +{ + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QObject *object = new QObject(&machine); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + + QState *s4 = new QState(machine.rootState()); + QObject::connect(s4, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", s2); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(pa); + + at = s2->addTransition(pa, SIGNAL(finished()), s3); + pa = new QPropertyAnimation(object, "foo", s3); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(pa); + + at = s3->addTransition(pa, SIGNAL(finished()), s4); + pa = new QPropertyAnimation(object, "foo", s4); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + at->addAnimation(pa); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s4)); + QCOMPARE(object->property("foo").toDouble(), 1.0); + QCOMPARE(counter.counter, 2); +} + +void tst_QStateMachine::specificTargetValueOfAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(&machine); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QPropertyAnimation *anim = new QPropertyAnimation(object, "foo"); + anim->setEndValue(10.0); + s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(anim); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + s2->addTransition(anim, SIGNAL(finished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); + QCOMPARE(anim->endValue().toDouble(), 10.0); +} + +void tst_QStateMachine::addDefaultAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); + machine.addDefaultAnimation(pa); + s2->addTransition(pa, SIGNAL(finished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation() +{ + QStateMachine machine; + + QObject *object = new QObject(&machine); + object->setProperty("foo", 1.0); + object->setProperty("bar", 2.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + machine.addDefaultAnimation(pa); + s2->addTransition(pa, SIGNAL(finished()), s3); + + pa = new QPropertyAnimation(object, "bar", &machine); + connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); + machine.addDefaultAnimation(pa); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); + QCOMPARE(counter.counter, 1); +} + +void tst_QStateMachine::removeDefaultAnimation() +{ + QStateMachine machine; + + QObject propertyHolder; + propertyHolder.setProperty("foo", 0); + + QCOMPARE(machine.defaultAnimations().size(), 0); + + QPropertyAnimation *anim = new QPropertyAnimation(&propertyHolder, "foo"); + + machine.addDefaultAnimation(anim); + + QCOMPARE(machine.defaultAnimations().size(), 1); + QVERIFY(machine.defaultAnimations().contains(anim)); + + machine.removeDefaultAnimation(anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + + machine.addDefaultAnimation(anim); + + QPropertyAnimation *anim2 = new QPropertyAnimation(&propertyHolder, "foo"); + machine.addDefaultAnimation(anim2); + + QCOMPARE(machine.defaultAnimations().size(), 2); + QVERIFY(machine.defaultAnimations().contains(anim)); + QVERIFY(machine.defaultAnimations().contains(anim2)); + + machine.removeDefaultAnimation(anim); + + QCOMPARE(machine.defaultAnimations().size(), 1); + QVERIFY(machine.defaultAnimations().contains(anim2)); + + machine.removeDefaultAnimation(anim2); + QCOMPARE(machine.defaultAnimations().size(), 0); +} + +void tst_QStateMachine::overrideDefaultAnimationWithSpecific() +{ + QStateMachine machine; + + QObject *object = new QObject(&machine); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimation(defaultAnimation); + at->addAnimation(moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +/* +void tst_QStateMachine::addDefaultAnimationForSource() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); + machine.addDefaultAnimationForSourceState(s1, pa); + s2->addTransition(pa, SIGNAL(finished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::addDefaultAnimationForTarget() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + QState *s1 = new QState(machine.rootState()); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); + machine.addDefaultAnimationForTargetState(s2, pa); + s2->addTransition(pa, SIGNAL(finished()), s3); + + machine.setInitialState(s1); + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(object->property("foo").toDouble(), 2.0); +} + +void tst_QStateMachine::removeDefaultAnimationForSource() +{ + QStateMachine machine; + + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + + QPropertyAnimation *anim = new QPropertyAnimation(this, "foo"); + + machine.addDefaultAnimationForSourceState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); + + machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); + + machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + + machine.addDefaultAnimationForSourceState(machine.rootState(), anim); + + QPropertyAnimation *anim2 = new QPropertyAnimation(this, "foo"); + machine.addDefaultAnimationForSourceState(machine.rootState(), anim2); + + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 2); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim2)); + + machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim2)); + + machine.removeDefaultAnimationForSourceState(machine.rootState(), anim2); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); +} + +void tst_QStateMachine::removeDefaultAnimationForTarget() +{ + QStateMachine machine; + + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + + QPropertyAnimation *anim = new QPropertyAnimation(this, "foo"); + + machine.addDefaultAnimationForTargetState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); + + machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimations().size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); + + machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + + machine.addDefaultAnimationForTargetState(machine.rootState(), anim); + + QPropertyAnimation *anim2 = new QPropertyAnimation(this, "foo"); + machine.addDefaultAnimationForTargetState(machine.rootState(), anim2); + + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 2); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim2)); + + machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); + + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); + QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim2)); + + machine.removeDefaultAnimationForTargetState(machine.rootState(), anim2); + QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); +} + +void tst_QStateMachine::overrideDefaultAnimationWithSource() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimation(defaultAnimation); + machine.addDefaultAnimationForSourceState(s1, moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +void tst_QStateMachine::overrideDefaultAnimationWithTarget() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimation(defaultAnimation); + machine.addDefaultAnimationForTargetState(s2, moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped + +} + +void tst_QStateMachine::overrideDefaultSourceAnimationWithSpecific() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimationForSourceState(s1, defaultAnimation); + at->addAnimation(moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +void tst_QStateMachine::overrideDefaultTargetAnimationWithSpecific() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimationForTargetState(s2, defaultAnimation); + at->addAnimation(moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +void tst_QStateMachine::overrideDefaultTargetAnimationWithSource() +{ + QStateMachine machine; + + QObject *object = new QObject(); + object->setProperty("foo", 1.0); + + SlotCalledCounter counter; + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(object, "foo", 2.0); + + QState *s3 = new QState(machine.rootState()); + QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + + QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); + connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); + s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); + connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); + + machine.addDefaultAnimationForTargetState(s2, defaultAnimation); + machine.addDefaultAnimationForSourceState(s1, moreSpecificAnimation); + + machine.start(); + QCoreApplication::processEvents(); + + machine.postEvent(new QEvent(QEvent::User)); + QCOREAPPLICATION_EXEC(5000); + + QVERIFY(machine.configuration().contains(s3)); + QCOMPARE(counter.counter, 2); // specific animation started and stopped +} + +*/ + +void tst_QStateMachine::parallelStateAssignmentsDone() +{ + QStateMachine machine; + + QObject *propertyHolder = new QObject(&machine); + propertyHolder->setProperty("foo", 123); + propertyHolder->setProperty("bar", 456); + propertyHolder->setProperty("zoot", 789); + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); + parallelState->assignProperty(propertyHolder, "foo", 321); + + QState *s2 = new QState(parallelState); + s2->assignProperty(propertyHolder, "bar", 654); + + QState *s3 = new QState(parallelState); + s3->assignProperty(propertyHolder, "zoot", 987); + + s1->addTransition(new EventTransition(QEvent::User, parallelState)); + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("foo").toInt(), 123); + QCOMPARE(propertyHolder->property("bar").toInt(), 456); + QCOMPARE(propertyHolder->property("zoot").toInt(), 789); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(propertyHolder->property("foo").toInt(), 321); + QCOMPARE(propertyHolder->property("bar").toInt(), 654); + QCOMPARE(propertyHolder->property("zoot").toInt(), 987); +} + +void tst_QStateMachine::transitionsFromParallelStateWithNoChildren() +{ + QStateMachine machine; + + QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); + machine.setInitialState(parallelState); + + QState *s1 = new QState(machine.rootState()); + parallelState->addTransition(new EventTransition(QEvent::User, s1)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(1, machine.configuration().size()); + QVERIFY(machine.configuration().contains(parallelState)); + + machine.postEvent(new QEvent(QEvent::User)); + + QCoreApplication::processEvents(); + + QCOMPARE(1, machine.configuration().size()); + QVERIFY(machine.configuration().contains(s1)); +} + +void tst_QStateMachine::parallelStateTransition() +{ + QStateMachine machine; + + QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); + machine.setInitialState(parallelState); + + QState *s1 = new QState(parallelState); + QState *s2 = new QState(parallelState); + + QState *s1InitialChild = new QState(s1); + s1->setInitialState(s1InitialChild); + + QState *s2InitialChild = new QState(s2); + s2->setInitialState(s2InitialChild); + + QState *s1OtherChild = new QState(s1); + + s1->addTransition(new EventTransition(QEvent::User, s1OtherChild)); + + machine.start(); + QCoreApplication::processEvents(); + + QVERIFY(machine.configuration().contains(parallelState)); + QVERIFY(machine.configuration().contains(s1)); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s1InitialChild)); + QVERIFY(machine.configuration().contains(s2InitialChild)); + QCOMPARE(machine.configuration().size(), 5); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QVERIFY(machine.configuration().contains(parallelState)); + + QVERIFY(machine.configuration().contains(s1)); + + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s1OtherChild)); + QVERIFY(machine.configuration().contains(s2InitialChild)); + QCOMPARE(machine.configuration().size(), 5); + +} + +void tst_QStateMachine::nestedRestoreProperties() +{ + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QObject *propertyHolder = new QObject(&machine); + propertyHolder->setProperty("foo", 1); + propertyHolder->setProperty("bar", 2); + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(propertyHolder, "foo", 3); + + QState *s21 = new QState(s2); + s21->assignProperty(propertyHolder, "bar", 4); + s2->setInitialState(s21); + + QState *s22 = new QState(s2); + s22->assignProperty(propertyHolder, "bar", 5); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s21->addTransition(new EventTransition(QEvent::User, s22)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + QCOMPARE(propertyHolder->property("foo").toInt(), 1); + QCOMPARE(propertyHolder->property("bar").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s21)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s22)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 5); +} + +void tst_QStateMachine::nestedRestoreProperties2() +{ + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QObject *propertyHolder = new QObject(&machine); + propertyHolder->setProperty("foo", 1); + propertyHolder->setProperty("bar", 2); + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(propertyHolder, "foo", 3); + + QState *s21 = new QState(s2); + s21->assignProperty(propertyHolder, "bar", 4); + s2->setInitialState(s21); + + QState *s22 = new QState(s2); + s22->assignProperty(propertyHolder, "foo", 6); + s22->assignProperty(propertyHolder, "bar", 5); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s21->addTransition(new EventTransition(QEvent::User, s22)); + s22->addTransition(new EventTransition(QEvent::User, s21)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + QCOMPARE(propertyHolder->property("foo").toInt(), 1); + QCOMPARE(propertyHolder->property("bar").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s21)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s22)); + QCOMPARE(propertyHolder->property("foo").toInt(), 6); + QCOMPARE(propertyHolder->property("bar").toInt(), 5); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s21)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 4); + +} + + +QTEST_MAIN(tst_QStateMachine) +#include "tst_qstatemachine.moc" diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index 8e2c243..4c39373 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs SUBDIRS = containers-associative \ containers-sequential \ + qanimation \ qbytearray \ qpainter \ qtestlib-simple events \ diff --git a/tests/benchmarks/qanimation/dummyanimation.cpp b/tests/benchmarks/qanimation/dummyanimation.cpp new file mode 100644 index 0000000..6fb1d0a --- /dev/null +++ b/tests/benchmarks/qanimation/dummyanimation.cpp @@ -0,0 +1,20 @@ +#include "dummyanimation.h" +#include "dummyobject.h" + + +DummyAnimation::DummyAnimation(DummyObject *d) : m_dummy(d) +{ +} + +void DummyAnimation::updateCurrentValue(const QVariant &value) +{ + if (state() == Stopped) + return; + if (m_dummy) + m_dummy->setRect(value.toRect()); +} + +void DummyAnimation::updateState(State state) +{ + Q_UNUSED(state); +} diff --git a/tests/benchmarks/qanimation/dummyanimation.h b/tests/benchmarks/qanimation/dummyanimation.h new file mode 100644 index 0000000..fe6592b --- /dev/null +++ b/tests/benchmarks/qanimation/dummyanimation.h @@ -0,0 +1,19 @@ +#include + +#ifndef _DUMMYANIMATION_H__ + +class DummyObject; + +class DummyAnimation : public QVariantAnimation +{ +public: + DummyAnimation(DummyObject *d); + + void updateCurrentValue(const QVariant &value); + void updateState(State state); + +private: + DummyObject *m_dummy; +}; + +#endif \ No newline at end of file diff --git a/tests/benchmarks/qanimation/dummyobject.cpp b/tests/benchmarks/qanimation/dummyobject.cpp new file mode 100644 index 0000000..bd76388 --- /dev/null +++ b/tests/benchmarks/qanimation/dummyobject.cpp @@ -0,0 +1,25 @@ +#include "dummyobject.h" + +DummyObject::DummyObject() +{ +} + +QRect DummyObject::rect() const +{ + return m_rect; +} + +void DummyObject::setRect(const QRect &r) +{ + m_rect = r; +} + +float DummyObject::opacity() const +{ + return m_opacity; +} + +void DummyObject::setOpacity(float o) +{ + m_opacity = o; +} diff --git a/tests/benchmarks/qanimation/dummyobject.h b/tests/benchmarks/qanimation/dummyobject.h new file mode 100644 index 0000000..c989662 --- /dev/null +++ b/tests/benchmarks/qanimation/dummyobject.h @@ -0,0 +1,23 @@ +#include + +#ifndef _DUMMYOBJECT_H__ + +class DummyObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(QRect rect READ rect WRITE setRect) + Q_PROPERTY(float opacity READ opacity WRITE setOpacity) +public: + DummyObject(); + QRect rect() const; + void setRect(const QRect &r); + float opacity() const; + void setOpacity(float); + +private: + QRect m_rect; + float m_opacity; +}; + + +#endif \ No newline at end of file diff --git a/tests/benchmarks/qanimation/main.cpp b/tests/benchmarks/qanimation/main.cpp new file mode 100644 index 0000000..7bb770f --- /dev/null +++ b/tests/benchmarks/qanimation/main.cpp @@ -0,0 +1,150 @@ +#include +#include + +#include "dummyobject.h" +#include "dummyanimation.h" +#include "rectanimation.h" + +#define ITERATION_COUNT 10e3 + +class tst_qanimation : public QObject +{ + Q_OBJECT +private slots: + void itemPropertyAnimation(); + void itemPropertyAnimation_data() { data();} + void dummyAnimation(); + void dummyAnimation_data() { data();} + void dummyPropertyAnimation(); + void dummyPropertyAnimation_data() { data();} + void rectAnimation(); + void rectAnimation_data() { data();} + + void floatAnimation_data() { data(); } + void floatAnimation(); + +private: + void data(); +}; + + +void tst_qanimation::data() +{ + QTest::addColumn("started"); + QTest::newRow("NotRunning") << false; + QTest::newRow("Running") << true; +} + +void tst_qanimation::itemPropertyAnimation() +{ + QFETCH(bool, started); + QGraphicsWidget item; + + //then the property animation + { + QPropertyAnimation anim(&item, "pos"); + anim.setDuration(ITERATION_COUNT); + anim.setStartValue(QPointF(0,0)); + anim.setEndValue(QPointF(ITERATION_COUNT,ITERATION_COUNT)); + if (started) + anim.start(); + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + anim.setCurrentTime(i); + } + } + } + +} + +void tst_qanimation::dummyAnimation() +{ + QFETCH(bool, started); + DummyObject dummy; + + //first the dummy animation + { + DummyAnimation anim(&dummy); + anim.setDuration(ITERATION_COUNT); + anim.setStartValue(QRect(0, 0, 0, 0)); + anim.setEndValue(QRect(0, 0, ITERATION_COUNT,ITERATION_COUNT)); + if (started) + anim.start(); + QBENCHMARK { + for(int i = 0; i < anim.duration(); ++i) { + anim.setCurrentTime(i); + } + } + } +} + +void tst_qanimation::dummyPropertyAnimation() +{ + QFETCH(bool, started); + DummyObject dummy; + + //then the property animation + { + QPropertyAnimation anim(&dummy, "rect"); + anim.setDuration(ITERATION_COUNT); + anim.setStartValue(QRect(0, 0, 0, 0)); + anim.setEndValue(QRect(0, 0, ITERATION_COUNT,ITERATION_COUNT)); + if (started) + anim.start(); + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + anim.setCurrentTime(i); + } + } + } +} + +void tst_qanimation::rectAnimation() +{ + //this is the simplest animation you can do + QFETCH(bool, started); + DummyObject dummy; + + //then the property animation + { + RectAnimation anim(&dummy); + anim.setDuration(ITERATION_COUNT); + anim.setStartValue(QRect(0, 0, 0, 0)); + anim.setEndValue(QRect(0, 0, ITERATION_COUNT,ITERATION_COUNT)); + if (started) + anim.start(); + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + anim.setCurrentTime(i); + } + } + } +} + +void tst_qanimation::floatAnimation() +{ + //this is the simplest animation you can do + QFETCH(bool, started); + DummyObject dummy; + + //then the property animation + { + QPropertyAnimation anim(&dummy, "opacity"); + anim.setDuration(ITERATION_COUNT); + anim.setStartValue(0.f); + anim.setEndValue(1.f); + if (started) + anim.start(); + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + anim.setCurrentTime(i); + } + } + } +} + + + +QTEST_MAIN(tst_qanimation) + +#include "main.moc" diff --git a/tests/benchmarks/qanimation/qanimation.pro b/tests/benchmarks/qanimation/qanimation.pro new file mode 100644 index 0000000..55cd75e --- /dev/null +++ b/tests/benchmarks/qanimation/qanimation.pro @@ -0,0 +1,18 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qanimation +DEPENDPATH += . +INCLUDEPATH += . + +CONFIG += release +#CONFIG += debug + + +SOURCES += main.cpp \ + dummyobject.cpp \ + dummyanimation.cpp \ + rectanimation.cpp + +HEADERS += dummyobject.h \ + dummyanimation.h \ + rectanimation.h diff --git a/tests/benchmarks/qanimation/rectanimation.cpp b/tests/benchmarks/qanimation/rectanimation.cpp new file mode 100644 index 0000000..d60a943 --- /dev/null +++ b/tests/benchmarks/qanimation/rectanimation.cpp @@ -0,0 +1,58 @@ +#include "rectanimation.h" +#include "dummyobject.h" + +static inline int interpolateInteger(int from, int to, qreal progress) +{ + return from + (to - from) * progress; +} + + +RectAnimation::RectAnimation(DummyObject *obj) : m_object(obj), m_dura(250) +{ +} + +void RectAnimation::setEndValue(const QRect &rect) +{ + m_end = rect; +} + +void RectAnimation::setStartValue(const QRect &rect) +{ + m_start = rect; +} + +void RectAnimation::setDuration(int d) +{ + m_dura = d; +} + +int RectAnimation::duration() const +{ + return m_dura; +} + + +void RectAnimation::updateCurrentTime(int msecs) +{ + qreal progress = m_easing.valueForProgress( qreal(msecs) / qreal(m_dura) ); + QRect now; + now.setCoords(interpolateInteger(m_start.left(), m_end.left(), progress), + interpolateInteger(m_start.top(), m_end.top(), progress), + interpolateInteger(m_start.right(), m_end.right(), progress), + interpolateInteger(m_start.bottom(), m_end.bottom(), progress)); + + bool changed = (now != m_current); + if (changed) + m_current = now; + + if (state() == Stopped) + return; + + if (m_object) + m_object->setRect(m_current); +} + +void RectAnimation::updateState(QAbstractAnimation::State state) +{ + Q_UNUSED(state); +} diff --git a/tests/benchmarks/qanimation/rectanimation.h b/tests/benchmarks/qanimation/rectanimation.h new file mode 100644 index 0000000..99b82b4 --- /dev/null +++ b/tests/benchmarks/qanimation/rectanimation.h @@ -0,0 +1,30 @@ +#include + +#ifndef _RECTANIMATION_H__ + +class DummyObject; + +//this class is even simpler than the dummy +//and uses no QVariant at all +class RectAnimation : public QAbstractAnimation +{ +public: + RectAnimation(DummyObject *obj); + + void setEndValue(const QRect &rect); + void setStartValue(const QRect &rect); + + void setDuration(int d); + int duration() const; + + virtual void updateCurrentTime(int msecs); + virtual void updateState(QAbstractAnimation::State state); + +private: + DummyObject *m_object; + QEasingCurve m_easing; + QRect m_start, m_end, m_current; + int m_dura; +}; + +#endif diff --git a/tests/benchmarks/qvariant/qvariant.pro b/tests/benchmarks/qvariant/qvariant.pro index 68b4a97..63b5442 100644 --- a/tests/benchmarks/qvariant/qvariant.pro +++ b/tests/benchmarks/qvariant/qvariant.pro @@ -3,7 +3,6 @@ TEMPLATE = app TARGET = tst_qvariant DEPENDPATH += . INCLUDEPATH += . -QT -= gui CONFIG += release #CONFIG += debug diff --git a/tests/benchmarks/qvariant/tst_qvariant.cpp b/tests/benchmarks/qvariant/tst_qvariant.cpp index 4a7ad02..0eb1ae2 100644 --- a/tests/benchmarks/qvariant/tst_qvariant.cpp +++ b/tests/benchmarks/qvariant/tst_qvariant.cpp @@ -38,7 +38,9 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include +#include #include #define ITERATION_COUNT 1e5 @@ -47,64 +49,73 @@ class tst_qvariant : public QObject { Q_OBJECT private slots: + void testBound(); + void doubleVariantCreation(); void floatVariantCreation(); void rectVariantCreation(); void stringVariantCreation(); + void pixmapVariantCreation(); + void doubleVariantSetValue(); void floatVariantSetValue(); void rectVariantSetValue(); void stringVariantSetValue(); + void doubleVariantAssignment(); void floatVariantAssignment(); void rectVariantAssignment(); void stringVariantAssignment(); }; - -void tst_qvariant::doubleVariantCreation() +void tst_qvariant::testBound() { - double d = 0; + qreal d = qreal(.5); QBENCHMARK { for(int i = 0; i < ITERATION_COUNT; ++i) { - QVariant v(d); + d = qBound(0, d, 1); } } } -void tst_qvariant::floatVariantCreation() +template +static void variantCreation(T val) { - float f = 0; QBENCHMARK { for(int i = 0; i < ITERATION_COUNT; ++i) { - QVariant v(f); + QVariant v(val); } } } +void tst_qvariant::doubleVariantCreation() +{ + variantCreation(0.0); +} + +void tst_qvariant::floatVariantCreation() +{ + variantCreation(0.0f); +} + void tst_qvariant::rectVariantCreation() { - QRect r(1,2,3,4); - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - QVariant v(r); - } - } + variantCreation(QRect(1, 2, 3, 4)); } void tst_qvariant::stringVariantCreation() { - QString s; - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - QVariant v(s); - } - } + variantCreation(QString()); } -void tst_qvariant::doubleVariantSetValue() +void tst_qvariant::pixmapVariantCreation() +{ + variantCreation(QPixmap()); +} + +template +static void variantSetValue(T d) { - double d = 0; QVariant v; QBENCHMARK { for(int i = 0; i < ITERATION_COUNT; ++i) { @@ -113,42 +124,29 @@ void tst_qvariant::doubleVariantSetValue() } } +void tst_qvariant::doubleVariantSetValue() +{ + variantSetValue(0.0); +} + void tst_qvariant::floatVariantSetValue() { - float f = 0; - QVariant v; - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - qVariantSetValue(v, f); - } - } + variantSetValue(0.0f); } void tst_qvariant::rectVariantSetValue() { - QRect r; - QVariant v; - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - qVariantSetValue(v, r); - } - } + variantSetValue(QRect()); } void tst_qvariant::stringVariantSetValue() { - QString s; - QVariant v; - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - qVariantSetValue(v, s); - } - } + variantSetValue(QString()); } -void tst_qvariant::doubleVariantAssignment() +template +static void variantAssignment(T d) { - double d = 0; QVariant v; QBENCHMARK { for(int i = 0; i < ITERATION_COUNT; ++i) { @@ -157,37 +155,24 @@ void tst_qvariant::doubleVariantAssignment() } } +void tst_qvariant::doubleVariantAssignment() +{ + variantAssignment(0.0); +} + void tst_qvariant::floatVariantAssignment() { - float f = 0; - QVariant v; - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - v = f; - } - } + variantAssignment(0.0f); } void tst_qvariant::rectVariantAssignment() { - QRect r; - QVariant v; - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - v = r; - } - } + variantAssignment(QRect()); } void tst_qvariant::stringVariantAssignment() { - QString s; - QVariant v; - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - v = s; - } - } + variantAssignment(QString()); } QTEST_MAIN(tst_qvariant) -- cgit v0.12 From 7c00cc50fc41a7c7b9c04e258a9eb03ff187c574 Mon Sep 17 00:00:00 2001 From: jasplin Date: Fri, 22 May 2009 13:23:39 +0200 Subject: Clarified doc for QGraphicsTextItem::setTextInteractionFlags(). Reviewed-by: TrustMe Task-number: 253559 --- src/gui/graphicsview/qgraphicsitem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 828dd4f..bd764b5 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -8837,9 +8837,9 @@ bool QGraphicsTextItemPrivate::_q_mouseOnEdge(QGraphicsSceneMouseEvent *event) Sets the flags \a flags to specify how the text item should react to user input. - The default for a QGraphicsTextItem is Qt::NoTextInteraction. Setting a - value different to Qt::NoTextInteraction will also set the ItemIsFocusable - QGraphicsItem flag. + The default for a QGraphicsTextItem is Qt::NoTextInteraction. This function + also affects the ItemIsFocusable QGraphicsItem flag by setting it if \a flags + is different from Qt::NoTextInteraction and clearing it otherwise. By default, the text is read-only. To transform the item into an editor, set the Qt::TextEditable flag. -- cgit v0.12 From bc498cd027dff6ff16032868c6bb00e634749cd6 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Fri, 22 May 2009 13:52:47 +0200 Subject: Fix Qt does not compile when glibc < 2.3.2 on linux Rather than try to resolve functions or impose configure time limitations we simply remove the dependancy entirely and rely on the fallbac for all platforms. Task-number: 250731 Reviewed-by: thiago --- src/gui/styles/gtksymbols.cpp | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index 0842ec7..d8a67c2 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -633,31 +633,14 @@ GtkStyle* QGtk::gtkStyle(const QString &path) return 0; } -#ifdef Q_OS_LINUX -QT_END_NAMESPACE - -int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); -int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); - -QT_BEGIN_NAMESPACE -#endif - void QGtk::initGtkWidgets() { // From gtkmain.c - - uid_t ruid, rgid, euid, egid, suid, sgid; - -#ifdef Q_OS_LINUX - if (getresuid (&ruid, &euid, &suid) != 0 || getresgid (&rgid, &egid, &sgid) != 0) -#endif - { - suid = ruid = getuid (); - sgid = rgid = getgid (); - euid = geteuid (); - egid = getegid (); - } - if (ruid != euid || ruid != suid || rgid != egid || rgid != sgid) { + uid_t ruid = getuid (); + uid_t rgid = getgid (); + uid_t euid = geteuid (); + uid_t egid = getegid (); + if (ruid != euid || rgid != egid) { qWarning("\nThis process is currently running setuid or setgid.\nGTK+ does not allow this " "therefore Qt cannot use the GTK+ integration.\nTry launching your app using \'gksudo\', " "\'kdesudo\' or a similar tool.\n\n" -- cgit v0.12 From b89efc8e7f3289ff85a5076297e4357283dd24a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 22 May 2009 12:27:48 +0200 Subject: Fixed text shaping bugs with ligatures and multiple font engines. If Harfbuzz shaping adds or merges glyphs we need to move the remaining glyphs in the glyph layout to compensate. Task-number: 253783 Reviewed-by: Simon Hausmann --- src/gui/text/qtextengine.cpp | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 80a5425..da1ab25 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1099,6 +1099,16 @@ void QTextEngine::shapeTextWithCE(int item) const } #endif +static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num) +{ + if (num > 0 && destination.glyphs != source.glyphs) { + memmove(destination.glyphs, source.glyphs, num * sizeof(HB_Glyph)); + memmove(destination.attributes, source.attributes, num * sizeof(HB_GlyphAttributes)); + memmove(destination.advances_x, source.advances_x, num * sizeof(HB_Fixed)); + memmove(destination.offsets, source.offsets, num * sizeof(HB_FixedPoint)); + } +} + /// take the item from layoutData->items and void QTextEngine::shapeTextWithHarfbuzz(int item) const { @@ -1189,7 +1199,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const - int initial_glyph_pos = 0; + int remaining_glyphs = entire_shaper_item.num_glyphs; int glyph_pos = 0; // for each item shape using harfbuzz and store the results in our layoutData's glyphs array. for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries @@ -1209,7 +1219,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const QFontEngine *actualFontEngine = font; uint engineIdx = 0; if (font->type() == QFontEngine::Multi) { - engineIdx = uint(initialGlyphs.glyphs[itemBoundaries[k + 1]] >> 24); + engineIdx = uint(initialGlyphs.glyphs[glyph_pos] >> 24); actualFontEngine = static_cast(font)->engine(engineIdx); } @@ -1219,16 +1229,18 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const shaper_item.glyphIndicesPresent = true; + remaining_glyphs -= shaper_item.initialGlyphCount; + do { - ensureSpace(glyph_pos + shaper_item.num_glyphs); - initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs); - shaper_item.num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used - glyph_pos; + ensureSpace(glyph_pos + shaper_item.num_glyphs + remaining_glyphs); - const QGlyphLayout g = availableGlyphs(&si); - shaper_item.glyphs = g.glyphs + glyph_pos; - shaper_item.attributes = g.attributes + glyph_pos; - shaper_item.advances = reinterpret_cast(g.advances_x + glyph_pos); - shaper_item.offsets = reinterpret_cast(g.offsets + glyph_pos); + const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos); + moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); + + shaper_item.glyphs = g.glyphs; + shaper_item.attributes = g.attributes; + shaper_item.advances = reinterpret_cast(g.advances_x); + shaper_item.offsets = reinterpret_cast(g.offsets); if (shaper_item.glyphIndicesPresent) { for (hb_uint32 i = 0; i < shaper_item.initialGlyphCount; ++i) @@ -1241,18 +1253,18 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const } while (!qShapeItem(&shaper_item)); // this does the actual shaping via harfbuzz. QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos, shaper_item.num_glyphs); + moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); - for (hb_uint32 i = 0; i < shaper_item.item.length; ++i) { + for (hb_uint32 i = 0; i < shaper_item.num_glyphs; ++i) g.glyphs[i] = g.glyphs[i] | (engineIdx << 24); + + for (hb_uint32 i = 0; i < shaper_item.item.length; ++i) shaper_item.log_clusters[i] += glyph_pos; - } if (kerningEnabled && !shaper_item.kerning_applied) font->doKerning(&g, option.useDesignMetrics() ? QFlag(QTextEngine::DesignMetrics) : QFlag(0)); glyph_pos += shaper_item.num_glyphs; - - initial_glyph_pos += shaper_item.initialGlyphCount; } // qDebug(" -> item: script=%d num_glyphs=%d", shaper_item.script, shaper_item.num_glyphs); -- cgit v0.12 From 64cc2368d230c6f0996a6311767bd1704b4cf322 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 14:09:21 +0200 Subject: Revert "Say hello to animation API & state machine API" This reverts commit 1a709fbe25a2446a9b311ded88aec5565258f3ac. --- demos/qtdemo/xml/examples.xml | 15 - doc/src/animation.qdoc | 368 -- doc/src/diagrams/animations-architecture.svg | 351 -- .../diagrams/programs/easingcurve/easingcurve.pro | 13 - doc/src/diagrams/programs/easingcurve/main.cpp | 90 - doc/src/examples-overview.qdoc | 8 - doc/src/examples.qdoc | 17 - doc/src/examples/eventtransitions.qdoc | 86 - doc/src/examples/factorial.qdoc | 102 - doc/src/examples/pingpong.qdoc | 107 - doc/src/examples/stickman.qdoc | 115 - doc/src/examples/tankgame.qdoc | 117 - doc/src/examples/trafficlight.qdoc | 99 - doc/src/examples/twowaybutton.qdoc | 82 - doc/src/external-resources.qdoc | 10 - doc/src/groups.qdoc | 23 - doc/src/images/animations-architecture.png | Bin 27619 -> 0 bytes doc/src/images/factorial-example.png | Bin 4032 -> 0 bytes doc/src/images/pingpong-example.png | Bin 7843 -> 0 bytes doc/src/images/qeasingcurve-cosinecurve.png | Bin 2544 -> 0 bytes doc/src/images/qeasingcurve-inback.png | Bin 2225 -> 0 bytes doc/src/images/qeasingcurve-inbounce.png | Bin 2378 -> 0 bytes doc/src/images/qeasingcurve-incirc.png | Bin 2138 -> 0 bytes doc/src/images/qeasingcurve-incubic.png | Bin 2230 -> 0 bytes doc/src/images/qeasingcurve-incurve.png | Bin 2325 -> 0 bytes doc/src/images/qeasingcurve-inelastic.png | Bin 2314 -> 0 bytes doc/src/images/qeasingcurve-inexpo.png | Bin 2183 -> 0 bytes doc/src/images/qeasingcurve-inoutback.png | Bin 2460 -> 0 bytes doc/src/images/qeasingcurve-inoutbounce.png | Bin 2522 -> 0 bytes doc/src/images/qeasingcurve-inoutcirc.png | Bin 2352 -> 0 bytes doc/src/images/qeasingcurve-inoutcubic.png | Bin 2410 -> 0 bytes doc/src/images/qeasingcurve-inoutelastic.png | Bin 2485 -> 0 bytes doc/src/images/qeasingcurve-inoutexpo.png | Bin 2383 -> 0 bytes doc/src/images/qeasingcurve-inoutquad.png | Bin 2392 -> 0 bytes doc/src/images/qeasingcurve-inoutquart.png | Bin 2331 -> 0 bytes doc/src/images/qeasingcurve-inoutquint.png | Bin 2244 -> 0 bytes doc/src/images/qeasingcurve-inoutsine.png | Bin 2405 -> 0 bytes doc/src/images/qeasingcurve-inquad.png | Bin 2283 -> 0 bytes doc/src/images/qeasingcurve-inquart.png | Bin 2261 -> 0 bytes doc/src/images/qeasingcurve-inquint.png | Bin 2178 -> 0 bytes doc/src/images/qeasingcurve-insine.png | Bin 2167 -> 0 bytes doc/src/images/qeasingcurve-linear.png | Bin 2165 -> 0 bytes doc/src/images/qeasingcurve-outback.png | Bin 2371 -> 0 bytes doc/src/images/qeasingcurve-outbounce.png | Bin 2481 -> 0 bytes doc/src/images/qeasingcurve-outcirc.png | Bin 2269 -> 0 bytes doc/src/images/qeasingcurve-outcubic.png | Bin 2336 -> 0 bytes doc/src/images/qeasingcurve-outcurve.png | Bin 2389 -> 0 bytes doc/src/images/qeasingcurve-outelastic.png | Bin 2402 -> 0 bytes doc/src/images/qeasingcurve-outexpo.png | Bin 2299 -> 0 bytes doc/src/images/qeasingcurve-outinback.png | Bin 2400 -> 0 bytes doc/src/images/qeasingcurve-outinbounce.png | Bin 2568 -> 0 bytes doc/src/images/qeasingcurve-outincirc.png | Bin 2339 -> 0 bytes doc/src/images/qeasingcurve-outincubic.png | Bin 2393 -> 0 bytes doc/src/images/qeasingcurve-outinelastic.png | Bin 2517 -> 0 bytes doc/src/images/qeasingcurve-outinexpo.png | Bin 2377 -> 0 bytes doc/src/images/qeasingcurve-outinquad.png | Bin 2380 -> 0 bytes doc/src/images/qeasingcurve-outinquart.png | Bin 2319 -> 0 bytes doc/src/images/qeasingcurve-outinquint.png | Bin 2248 -> 0 bytes doc/src/images/qeasingcurve-outinsine.png | Bin 2388 -> 0 bytes doc/src/images/qeasingcurve-outquad.png | Bin 2324 -> 0 bytes doc/src/images/qeasingcurve-outquart.png | Bin 2304 -> 0 bytes doc/src/images/qeasingcurve-outquint.png | Bin 2242 -> 0 bytes doc/src/images/qeasingcurve-outsine.png | Bin 2364 -> 0 bytes doc/src/images/qeasingcurve-sinecurve.png | Bin 2470 -> 0 bytes doc/src/images/statemachine-button-history.png | Bin 8493 -> 0 bytes doc/src/images/statemachine-button-nested.png | Bin 7051 -> 0 bytes doc/src/images/statemachine-button.png | Bin 4233 -> 0 bytes doc/src/images/statemachine-customevents.png | Bin 2544 -> 0 bytes doc/src/images/statemachine-customevents2.png | Bin 6713 -> 0 bytes doc/src/images/statemachine-finished.png | Bin 5518 -> 0 bytes doc/src/images/statemachine-nonparallel.png | Bin 5350 -> 0 bytes doc/src/images/statemachine-parallel.png | Bin 8631 -> 0 bytes doc/src/images/stickman-example.png | Bin 18867 -> 0 bytes doc/src/images/stickman-example1.png | Bin 64543 -> 0 bytes doc/src/images/stickman-example2.png | Bin 37412 -> 0 bytes doc/src/images/stickman-example3.png | Bin 23591 -> 0 bytes doc/src/images/tankgame-example.png | Bin 16089 -> 0 bytes doc/src/images/trafficlight-example.png | Bin 5325 -> 0 bytes doc/src/images/trafficlight-example1.png | Bin 3694 -> 0 bytes doc/src/images/trafficlight-example2.png | Bin 7257 -> 0 bytes doc/src/snippets/animation/sequential/icons.qrc | 6 - .../snippets/animation/sequential/icons/left.png | Bin 413 -> 0 bytes .../snippets/animation/sequential/icons/right.png | Bin 414 -> 0 bytes doc/src/snippets/animation/sequential/main.cpp | 50 - .../snippets/animation/sequential/sequential.pro | 4 - doc/src/snippets/animation/sequential/tracer.cpp | 25 - doc/src/snippets/animation/sequential/tracer.h | 23 - .../code/src_corelib_tools_qeasingcurve.cpp | 4 - doc/src/statemachine.qdoc | 645 ---- examples/animation/README | 38 - examples/animation/animatedtiles/animatedtiles.pro | 8 - examples/animation/animatedtiles/animatedtiles.qrc | 11 - .../animatedtiles/images/Time-For-Lunch-2.jpg | Bin 32471 -> 0 bytes .../animation/animatedtiles/images/centered.png | Bin 892 -> 0 bytes .../animation/animatedtiles/images/ellipse.png | Bin 10767 -> 0 bytes .../animation/animatedtiles/images/figure8.png | Bin 14050 -> 0 bytes .../animation/animatedtiles/images/kinetic.png | Bin 6776 -> 0 bytes examples/animation/animatedtiles/images/random.png | Bin 14969 -> 0 bytes examples/animation/animatedtiles/images/tile.png | Bin 16337 -> 0 bytes examples/animation/animatedtiles/main.cpp | 280 -- examples/animation/animation.pro | 16 - .../appchooser/accessories-dictionary.png | Bin 5396 -> 0 bytes examples/animation/appchooser/akregator.png | Bin 4873 -> 0 bytes examples/animation/appchooser/appchooser.pro | 8 - examples/animation/appchooser/appchooser.qrc | 8 - examples/animation/appchooser/digikam.png | Bin 3334 -> 0 bytes examples/animation/appchooser/k3b.png | Bin 8220 -> 0 bytes examples/animation/appchooser/main.cpp | 158 - examples/animation/easing/animation.h | 101 - examples/animation/easing/easing.pro | 14 - examples/animation/easing/easing.qrc | 5 - examples/animation/easing/form.ui | 201 -- examples/animation/easing/images/qt-logo.png | Bin 5149 -> 0 bytes examples/animation/easing/main.cpp | 53 - examples/animation/easing/window.cpp | 163 - examples/animation/easing/window.h | 79 - examples/animation/moveblocks/main.cpp | 296 -- examples/animation/moveblocks/moveblocks.pro | 7 - .../animation/states/accessories-dictionary.png | Bin 5396 -> 0 bytes examples/animation/states/akregator.png | Bin 4873 -> 0 bytes examples/animation/states/digikam.png | Bin 3334 -> 0 bytes examples/animation/states/help-browser.png | Bin 6984 -> 0 bytes examples/animation/states/k3b.png | Bin 8220 -> 0 bytes examples/animation/states/kchart.png | Bin 4887 -> 0 bytes examples/animation/states/main.cpp | 284 -- examples/animation/states/states.pro | 8 - examples/animation/states/states.qrc | 10 - examples/animation/stickman/animation.cpp | 193 -- examples/animation/stickman/animation.h | 83 - examples/animation/stickman/animations/chilling | Bin 6508 -> 0 bytes examples/animation/stickman/animations/dancing | Bin 2348 -> 0 bytes examples/animation/stickman/animations/dead | Bin 268 -> 0 bytes examples/animation/stickman/animations/jumping | Bin 1308 -> 0 bytes .../animation/stickman/editor/animationdialog.cpp | 192 -- .../animation/stickman/editor/animationdialog.h | 84 - examples/animation/stickman/editor/editor.pri | 2 - examples/animation/stickman/editor/mainwindow.cpp | 76 - examples/animation/stickman/editor/mainwindow.h | 58 - examples/animation/stickman/graphicsview.cpp | 81 - examples/animation/stickman/graphicsview.h | 64 - examples/animation/stickman/lifecycle.cpp | 212 -- examples/animation/stickman/lifecycle.h | 80 - examples/animation/stickman/main.cpp | 97 - examples/animation/stickman/node.cpp | 92 - examples/animation/stickman/node.h | 72 - examples/animation/stickman/stickman.cpp | 339 -- examples/animation/stickman/stickman.h | 103 - examples/animation/stickman/stickman.pro | 19 - examples/animation/sub-attaq/animationmanager.cpp | 93 - examples/animation/sub-attaq/animationmanager.h | 70 - examples/animation/sub-attaq/boat.cpp | 318 -- examples/animation/sub-attaq/boat.h | 102 - examples/animation/sub-attaq/boat_p.h | 256 -- examples/animation/sub-attaq/bomb.cpp | 124 - examples/animation/sub-attaq/bomb.h | 76 - .../sub-attaq/custompropertyanimation.cpp | 108 - .../animation/sub-attaq/custompropertyanimation.h | 114 - examples/animation/sub-attaq/data.xml | 15 - examples/animation/sub-attaq/graphicsscene.cpp | 374 --- examples/animation/sub-attaq/graphicsscene.h | 131 - examples/animation/sub-attaq/main.cpp | 57 - examples/animation/sub-attaq/mainwindow.cpp | 92 - examples/animation/sub-attaq/mainwindow.h | 64 - .../animation/sub-attaq/pics/big/background.png | Bin 48858 -> 0 bytes examples/animation/sub-attaq/pics/big/boat.png | Bin 5198 -> 0 bytes examples/animation/sub-attaq/pics/big/bomb.png | Bin 760 -> 0 bytes .../sub-attaq/pics/big/explosion/boat/step1.png | Bin 5760 -> 0 bytes .../sub-attaq/pics/big/explosion/boat/step2.png | Bin 9976 -> 0 bytes .../sub-attaq/pics/big/explosion/boat/step3.png | Bin 12411 -> 0 bytes .../sub-attaq/pics/big/explosion/boat/step4.png | Bin 15438 -> 0 bytes .../pics/big/explosion/submarine/step1.png | Bin 3354 -> 0 bytes .../pics/big/explosion/submarine/step2.png | Bin 6205 -> 0 bytes .../pics/big/explosion/submarine/step3.png | Bin 6678 -> 0 bytes .../pics/big/explosion/submarine/step4.png | Bin 6666 -> 0 bytes .../animation/sub-attaq/pics/big/submarine.png | Bin 3202 -> 0 bytes examples/animation/sub-attaq/pics/big/surface.png | Bin 575 -> 0 bytes examples/animation/sub-attaq/pics/big/torpedo.png | Bin 951 -> 0 bytes .../sub-attaq/pics/scalable/background-n810.svg | 171 - .../sub-attaq/pics/scalable/background.svg | 171 - .../animation/sub-attaq/pics/scalable/boat.svg | 279 -- .../animation/sub-attaq/pics/scalable/bomb.svg | 138 - .../animation/sub-attaq/pics/scalable/sand.svg | 103 - examples/animation/sub-attaq/pics/scalable/see.svg | 44 - examples/animation/sub-attaq/pics/scalable/sky.svg | 45 - .../sub-attaq/pics/scalable/sub-attaq.svg | 1473 -------- .../sub-attaq/pics/scalable/submarine.svg | 214 -- .../animation/sub-attaq/pics/scalable/surface.svg | 49 - .../animation/sub-attaq/pics/scalable/torpedo.svg | 127 - .../animation/sub-attaq/pics/small/background.png | Bin 34634 -> 0 bytes examples/animation/sub-attaq/pics/small/boat.png | Bin 2394 -> 0 bytes examples/animation/sub-attaq/pics/small/bomb.png | Bin 760 -> 0 bytes .../animation/sub-attaq/pics/small/submarine.png | Bin 1338 -> 0 bytes .../animation/sub-attaq/pics/small/surface.png | Bin 502 -> 0 bytes .../animation/sub-attaq/pics/small/torpedo.png | Bin 951 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-a.png | Bin 5972 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-a2.png | Bin 5969 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-b.png | Bin 6869 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-dash.png | Bin 2255 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-excl.png | Bin 2740 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-q.png | Bin 7016 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-s.png | Bin 5817 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-t.png | Bin 3717 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-t2.png | Bin 3688 -> 0 bytes .../animation/sub-attaq/pics/welcome/logo-u.png | Bin 5374 -> 0 bytes examples/animation/sub-attaq/pixmapitem.cpp | 59 - examples/animation/sub-attaq/pixmapitem.h | 63 - examples/animation/sub-attaq/progressitem.cpp | 67 - examples/animation/sub-attaq/progressitem.h | 61 - examples/animation/sub-attaq/qanimationstate.cpp | 171 - examples/animation/sub-attaq/qanimationstate.h | 92 - examples/animation/sub-attaq/states.cpp | 325 -- examples/animation/sub-attaq/states.h | 180 - examples/animation/sub-attaq/sub-attaq.pro | 36 - examples/animation/sub-attaq/subattaq.qrc | 38 - examples/animation/sub-attaq/submarine.cpp | 211 -- examples/animation/sub-attaq/submarine.h | 92 - examples/animation/sub-attaq/submarine_p.h | 139 - examples/animation/sub-attaq/torpedo.cpp | 120 - examples/animation/sub-attaq/torpedo.h | 76 - examples/examples.pro | 2 - examples/statemachine/README | 36 - .../eventtransitions/eventtransitions.pro | 7 - examples/statemachine/eventtransitions/main.cpp | 116 - examples/statemachine/factorial/factorial.pro | 11 - examples/statemachine/factorial/main.cpp | 182 - examples/statemachine/pingpong/main.cpp | 145 - examples/statemachine/pingpong/pingpong.pro | 11 - examples/statemachine/statemachine.pro | 15 - examples/statemachine/tankgame/gameitem.cpp | 129 - examples/statemachine/tankgame/gameitem.h | 66 - .../statemachine/tankgame/gameovertransition.cpp | 80 - .../statemachine/tankgame/gameovertransition.h | 63 - examples/statemachine/tankgame/main.cpp | 53 - examples/statemachine/tankgame/mainwindow.cpp | 342 -- examples/statemachine/tankgame/mainwindow.h | 93 - examples/statemachine/tankgame/plugin.h | 62 - examples/statemachine/tankgame/rocketitem.cpp | 101 - examples/statemachine/tankgame/rocketitem.h | 66 - examples/statemachine/tankgame/tankgame.pro | 19 - examples/statemachine/tankgame/tankitem.cpp | 302 -- examples/statemachine/tankgame/tankitem.h | 109 - .../tankgameplugins/random_ai/random_ai.pro | 13 - .../tankgameplugins/random_ai/random_ai_plugin.cpp | 79 - .../tankgameplugins/random_ai/random_ai_plugin.h | 105 - .../tankgameplugins/seek_ai/seek_ai.cpp | 89 - .../statemachine/tankgameplugins/seek_ai/seek_ai.h | 249 -- .../tankgameplugins/seek_ai/seek_ai.pro | 13 - .../tankgameplugins/spin_ai/spin_ai.cpp | 70 - .../statemachine/tankgameplugins/spin_ai/spin_ai.h | 92 - .../tankgameplugins/spin_ai/spin_ai.pro | 13 - .../spin_ai_with_error/spin_ai_with_error.cpp | 70 - .../spin_ai_with_error/spin_ai_with_error.h | 92 - .../spin_ai_with_error/spin_ai_with_error.pro | 13 - .../tankgameplugins/tankgameplugins.pro | 11 - examples/statemachine/trafficlight/main.cpp | 190 -- .../statemachine/trafficlight/trafficlight.pro | 7 - examples/statemachine/twowaybutton/main.cpp | 86 - .../statemachine/twowaybutton/twowaybutton.pro | 7 - mkspecs/win32-icc/qmake.conf | 2 +- src/3rdparty/easing/easing.cpp | 670 ---- src/3rdparty/easing/legal.qdoc | 35 - src/corelib/animation/animation.pri | 25 - src/corelib/animation/qabstractanimation.cpp | 759 ----- src/corelib/animation/qabstractanimation.h | 137 - src/corelib/animation/qabstractanimation_p.h | 136 - src/corelib/animation/qanimationgroup.cpp | 309 -- src/corelib/animation/qanimationgroup.h | 88 - src/corelib/animation/qanimationgroup_p.h | 79 - src/corelib/animation/qparallelanimationgroup.cpp | 316 -- src/corelib/animation/qparallelanimationgroup.h | 86 - src/corelib/animation/qparallelanimationgroup_p.h | 85 - src/corelib/animation/qpauseanimation.cpp | 154 - src/corelib/animation/qpauseanimation.h | 84 - src/corelib/animation/qpropertyanimation.cpp | 316 -- src/corelib/animation/qpropertyanimation.h | 90 - src/corelib/animation/qpropertyanimation_p.h | 89 - .../animation/qsequentialanimationgroup.cpp | 594 ---- src/corelib/animation/qsequentialanimationgroup.h | 96 - .../animation/qsequentialanimationgroup_p.h | 111 - src/corelib/animation/qvariantanimation.cpp | 644 ---- src/corelib/animation/qvariantanimation.h | 130 - src/corelib/animation/qvariantanimation_p.h | 130 - src/corelib/corelib.pro | 2 - src/corelib/kernel/kernel.pri | 8 +- src/corelib/kernel/qcoreevent.cpp | 2 - src/corelib/kernel/qcoreevent.h | 8 +- src/corelib/statemachine/qabstractstate.cpp | 202 -- src/corelib/statemachine/qabstractstate.h | 90 - src/corelib/statemachine/qabstractstate_p.h | 84 - src/corelib/statemachine/qabstracttransition.cpp | 342 -- src/corelib/statemachine/qabstracttransition.h | 111 - src/corelib/statemachine/qabstracttransition_p.h | 91 - src/corelib/statemachine/qeventtransition.cpp | 282 -- src/corelib/statemachine/qeventtransition.h | 96 - src/corelib/statemachine/qeventtransition_p.h | 78 - src/corelib/statemachine/qfinalstate.cpp | 134 - src/corelib/statemachine/qfinalstate.h | 76 - src/corelib/statemachine/qhistorystate.cpp | 223 -- src/corelib/statemachine/qhistorystate.h | 91 - src/corelib/statemachine/qhistorystate_p.h | 79 - src/corelib/statemachine/qsignalevent.h | 77 - src/corelib/statemachine/qsignaleventgenerator_p.h | 78 - src/corelib/statemachine/qsignaltransition.cpp | 257 -- src/corelib/statemachine/qsignaltransition.h | 89 - src/corelib/statemachine/qsignaltransition_p.h | 78 - src/corelib/statemachine/qstate.cpp | 497 --- src/corelib/statemachine/qstate.h | 113 - src/corelib/statemachine/qstate_p.h | 108 - src/corelib/statemachine/qstatemachine.cpp | 2216 ------------ src/corelib/statemachine/qstatemachine.h | 166 - src/corelib/statemachine/qstatemachine_p.h | 217 -- src/corelib/statemachine/qwrappedevent.h | 76 - src/corelib/statemachine/statemachine.pri | 30 - src/corelib/tools/qeasingcurve.cpp | 846 ----- src/corelib/tools/qeasingcurve.h | 114 - src/corelib/tools/qtimeline.cpp | 114 +- src/corelib/tools/qtimeline.h | 5 - src/corelib/tools/tools.pri | 2 - src/gui/animation/animation.pri | 3 - src/gui/animation/qguivariantanimation.cpp | 75 - src/gui/graphicsview/qgraphicsitem_p.h | 12 +- src/gui/graphicsview/qgraphicsproxywidget.cpp | 2 - src/gui/graphicsview/qgraphicsproxywidget.h | 2 - src/gui/gui.pro | 2 - src/gui/kernel/qapplication.cpp | 6 - src/gui/painting/qdrawhelper.cpp | 8 +- src/gui/statemachine/qbasickeyeventtransition.cpp | 203 -- src/gui/statemachine/qbasickeyeventtransition_p.h | 93 - .../statemachine/qbasicmouseeventtransition.cpp | 208 -- .../statemachine/qbasicmouseeventtransition_p.h | 98 - src/gui/statemachine/qguistatemachine.cpp | 559 --- src/gui/statemachine/qkeyeventtransition.cpp | 186 - src/gui/statemachine/qkeyeventtransition.h | 87 - src/gui/statemachine/qmouseeventtransition.cpp | 216 -- src/gui/statemachine/qmouseeventtransition.h | 92 - src/gui/statemachine/statemachine.pri | 13 - tests/auto/auto.pro | 6 - tests/auto/qanimationgroup/qanimationgroup.pro | 5 - tests/auto/qanimationgroup/tst_qanimationgroup.cpp | 413 --- tests/auto/qeasingcurve/qeasingcurve.pro | 3 - tests/auto/qeasingcurve/tst_qeasingcurve.cpp | 487 --- tests/auto/qmake/testdata/bundle-spaces/some-file | 6 - .../qparallelanimationgroup.pro | 5 - .../tst_qparallelanimationgroup.cpp | 834 ----- .../auto/qpropertyanimation/qpropertyanimation.pro | 5 - .../qpropertyanimation/tst_qpropertyanimation.cpp | 919 ----- .../qsequentialanimationgroup.pro | 5 - .../tst_qsequentialanimationgroup.cpp | 1649 --------- tests/auto/qstate/qstate.pro | 5 - tests/auto/qstate/tst_qstate.cpp | 340 -- tests/auto/qstatemachine/qstatemachine.pro | 4 - tests/auto/qstatemachine/tst_qstatemachine.cpp | 3548 -------------------- tests/benchmarks/benchmarks.pro | 1 - tests/benchmarks/qanimation/dummyanimation.cpp | 20 - tests/benchmarks/qanimation/dummyanimation.h | 19 - tests/benchmarks/qanimation/dummyobject.cpp | 25 - tests/benchmarks/qanimation/dummyobject.h | 23 - tests/benchmarks/qanimation/main.cpp | 150 - tests/benchmarks/qanimation/qanimation.pro | 18 - tests/benchmarks/qanimation/rectanimation.cpp | 58 - tests/benchmarks/qanimation/rectanimation.h | 30 - tests/benchmarks/qvariant/qvariant.pro | 1 + tests/benchmarks/qvariant/tst_qvariant.cpp | 115 +- 363 files changed, 130 insertions(+), 38378 deletions(-) delete mode 100644 doc/src/animation.qdoc delete mode 100644 doc/src/diagrams/animations-architecture.svg delete mode 100644 doc/src/diagrams/programs/easingcurve/easingcurve.pro delete mode 100644 doc/src/diagrams/programs/easingcurve/main.cpp delete mode 100644 doc/src/examples/eventtransitions.qdoc delete mode 100644 doc/src/examples/factorial.qdoc delete mode 100644 doc/src/examples/pingpong.qdoc delete mode 100644 doc/src/examples/stickman.qdoc delete mode 100644 doc/src/examples/tankgame.qdoc delete mode 100644 doc/src/examples/trafficlight.qdoc delete mode 100644 doc/src/examples/twowaybutton.qdoc delete mode 100644 doc/src/images/animations-architecture.png delete mode 100644 doc/src/images/factorial-example.png delete mode 100644 doc/src/images/pingpong-example.png delete mode 100644 doc/src/images/qeasingcurve-cosinecurve.png delete mode 100644 doc/src/images/qeasingcurve-inback.png delete mode 100644 doc/src/images/qeasingcurve-inbounce.png delete mode 100644 doc/src/images/qeasingcurve-incirc.png delete mode 100644 doc/src/images/qeasingcurve-incubic.png delete mode 100644 doc/src/images/qeasingcurve-incurve.png delete mode 100644 doc/src/images/qeasingcurve-inelastic.png delete mode 100644 doc/src/images/qeasingcurve-inexpo.png delete mode 100644 doc/src/images/qeasingcurve-inoutback.png delete mode 100644 doc/src/images/qeasingcurve-inoutbounce.png delete mode 100644 doc/src/images/qeasingcurve-inoutcirc.png delete mode 100644 doc/src/images/qeasingcurve-inoutcubic.png delete mode 100644 doc/src/images/qeasingcurve-inoutelastic.png delete mode 100644 doc/src/images/qeasingcurve-inoutexpo.png delete mode 100644 doc/src/images/qeasingcurve-inoutquad.png delete mode 100644 doc/src/images/qeasingcurve-inoutquart.png delete mode 100644 doc/src/images/qeasingcurve-inoutquint.png delete mode 100644 doc/src/images/qeasingcurve-inoutsine.png delete mode 100644 doc/src/images/qeasingcurve-inquad.png delete mode 100644 doc/src/images/qeasingcurve-inquart.png delete mode 100644 doc/src/images/qeasingcurve-inquint.png delete mode 100644 doc/src/images/qeasingcurve-insine.png delete mode 100644 doc/src/images/qeasingcurve-linear.png delete mode 100644 doc/src/images/qeasingcurve-outback.png delete mode 100644 doc/src/images/qeasingcurve-outbounce.png delete mode 100644 doc/src/images/qeasingcurve-outcirc.png delete mode 100644 doc/src/images/qeasingcurve-outcubic.png delete mode 100644 doc/src/images/qeasingcurve-outcurve.png delete mode 100644 doc/src/images/qeasingcurve-outelastic.png delete mode 100644 doc/src/images/qeasingcurve-outexpo.png delete mode 100644 doc/src/images/qeasingcurve-outinback.png delete mode 100644 doc/src/images/qeasingcurve-outinbounce.png delete mode 100644 doc/src/images/qeasingcurve-outincirc.png delete mode 100644 doc/src/images/qeasingcurve-outincubic.png delete mode 100644 doc/src/images/qeasingcurve-outinelastic.png delete mode 100644 doc/src/images/qeasingcurve-outinexpo.png delete mode 100644 doc/src/images/qeasingcurve-outinquad.png delete mode 100644 doc/src/images/qeasingcurve-outinquart.png delete mode 100644 doc/src/images/qeasingcurve-outinquint.png delete mode 100644 doc/src/images/qeasingcurve-outinsine.png delete mode 100644 doc/src/images/qeasingcurve-outquad.png delete mode 100644 doc/src/images/qeasingcurve-outquart.png delete mode 100644 doc/src/images/qeasingcurve-outquint.png delete mode 100644 doc/src/images/qeasingcurve-outsine.png delete mode 100644 doc/src/images/qeasingcurve-sinecurve.png delete mode 100644 doc/src/images/statemachine-button-history.png delete mode 100644 doc/src/images/statemachine-button-nested.png delete mode 100644 doc/src/images/statemachine-button.png delete mode 100644 doc/src/images/statemachine-customevents.png delete mode 100644 doc/src/images/statemachine-customevents2.png delete mode 100644 doc/src/images/statemachine-finished.png delete mode 100644 doc/src/images/statemachine-nonparallel.png delete mode 100644 doc/src/images/statemachine-parallel.png delete mode 100644 doc/src/images/stickman-example.png delete mode 100644 doc/src/images/stickman-example1.png delete mode 100644 doc/src/images/stickman-example2.png delete mode 100644 doc/src/images/stickman-example3.png delete mode 100644 doc/src/images/tankgame-example.png delete mode 100644 doc/src/images/trafficlight-example.png delete mode 100644 doc/src/images/trafficlight-example1.png delete mode 100644 doc/src/images/trafficlight-example2.png delete mode 100644 doc/src/snippets/animation/sequential/icons.qrc delete mode 100644 doc/src/snippets/animation/sequential/icons/left.png delete mode 100644 doc/src/snippets/animation/sequential/icons/right.png delete mode 100644 doc/src/snippets/animation/sequential/main.cpp delete mode 100644 doc/src/snippets/animation/sequential/sequential.pro delete mode 100644 doc/src/snippets/animation/sequential/tracer.cpp delete mode 100644 doc/src/snippets/animation/sequential/tracer.h delete mode 100644 doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp delete mode 100644 doc/src/statemachine.qdoc delete mode 100644 examples/animation/README delete mode 100644 examples/animation/animatedtiles/animatedtiles.pro delete mode 100644 examples/animation/animatedtiles/animatedtiles.qrc delete mode 100644 examples/animation/animatedtiles/images/Time-For-Lunch-2.jpg delete mode 100644 examples/animation/animatedtiles/images/centered.png delete mode 100644 examples/animation/animatedtiles/images/ellipse.png delete mode 100644 examples/animation/animatedtiles/images/figure8.png delete mode 100644 examples/animation/animatedtiles/images/kinetic.png delete mode 100644 examples/animation/animatedtiles/images/random.png delete mode 100644 examples/animation/animatedtiles/images/tile.png delete mode 100644 examples/animation/animatedtiles/main.cpp delete mode 100644 examples/animation/animation.pro delete mode 100644 examples/animation/appchooser/accessories-dictionary.png delete mode 100644 examples/animation/appchooser/akregator.png delete mode 100644 examples/animation/appchooser/appchooser.pro delete mode 100644 examples/animation/appchooser/appchooser.qrc delete mode 100644 examples/animation/appchooser/digikam.png delete mode 100644 examples/animation/appchooser/k3b.png delete mode 100644 examples/animation/appchooser/main.cpp delete mode 100644 examples/animation/easing/animation.h delete mode 100644 examples/animation/easing/easing.pro delete mode 100644 examples/animation/easing/easing.qrc delete mode 100644 examples/animation/easing/form.ui delete mode 100644 examples/animation/easing/images/qt-logo.png delete mode 100644 examples/animation/easing/main.cpp delete mode 100644 examples/animation/easing/window.cpp delete mode 100644 examples/animation/easing/window.h delete mode 100644 examples/animation/moveblocks/main.cpp delete mode 100644 examples/animation/moveblocks/moveblocks.pro delete mode 100644 examples/animation/states/accessories-dictionary.png delete mode 100644 examples/animation/states/akregator.png delete mode 100644 examples/animation/states/digikam.png delete mode 100644 examples/animation/states/help-browser.png delete mode 100644 examples/animation/states/k3b.png delete mode 100644 examples/animation/states/kchart.png delete mode 100644 examples/animation/states/main.cpp delete mode 100644 examples/animation/states/states.pro delete mode 100644 examples/animation/states/states.qrc delete mode 100644 examples/animation/stickman/animation.cpp delete mode 100644 examples/animation/stickman/animation.h delete mode 100644 examples/animation/stickman/animations/chilling delete mode 100644 examples/animation/stickman/animations/dancing delete mode 100644 examples/animation/stickman/animations/dead delete mode 100644 examples/animation/stickman/animations/jumping delete mode 100644 examples/animation/stickman/editor/animationdialog.cpp delete mode 100644 examples/animation/stickman/editor/animationdialog.h delete mode 100644 examples/animation/stickman/editor/editor.pri delete mode 100644 examples/animation/stickman/editor/mainwindow.cpp delete mode 100644 examples/animation/stickman/editor/mainwindow.h delete mode 100644 examples/animation/stickman/graphicsview.cpp delete mode 100644 examples/animation/stickman/graphicsview.h delete mode 100644 examples/animation/stickman/lifecycle.cpp delete mode 100644 examples/animation/stickman/lifecycle.h delete mode 100644 examples/animation/stickman/main.cpp delete mode 100644 examples/animation/stickman/node.cpp delete mode 100644 examples/animation/stickman/node.h delete mode 100644 examples/animation/stickman/stickman.cpp delete mode 100644 examples/animation/stickman/stickman.h delete mode 100644 examples/animation/stickman/stickman.pro delete mode 100644 examples/animation/sub-attaq/animationmanager.cpp delete mode 100644 examples/animation/sub-attaq/animationmanager.h delete mode 100644 examples/animation/sub-attaq/boat.cpp delete mode 100644 examples/animation/sub-attaq/boat.h delete mode 100644 examples/animation/sub-attaq/boat_p.h delete mode 100644 examples/animation/sub-attaq/bomb.cpp delete mode 100644 examples/animation/sub-attaq/bomb.h delete mode 100644 examples/animation/sub-attaq/custompropertyanimation.cpp delete mode 100644 examples/animation/sub-attaq/custompropertyanimation.h delete mode 100644 examples/animation/sub-attaq/data.xml delete mode 100644 examples/animation/sub-attaq/graphicsscene.cpp delete mode 100644 examples/animation/sub-attaq/graphicsscene.h delete mode 100644 examples/animation/sub-attaq/main.cpp delete mode 100644 examples/animation/sub-attaq/mainwindow.cpp delete mode 100644 examples/animation/sub-attaq/mainwindow.h delete mode 100644 examples/animation/sub-attaq/pics/big/background.png delete mode 100644 examples/animation/sub-attaq/pics/big/boat.png delete mode 100644 examples/animation/sub-attaq/pics/big/bomb.png delete mode 100644 examples/animation/sub-attaq/pics/big/explosion/boat/step1.png delete mode 100644 examples/animation/sub-attaq/pics/big/explosion/boat/step2.png delete mode 100644 examples/animation/sub-attaq/pics/big/explosion/boat/step3.png delete mode 100644 examples/animation/sub-attaq/pics/big/explosion/boat/step4.png delete mode 100644 examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png delete mode 100644 examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png delete mode 100644 examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png delete mode 100644 examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png delete mode 100644 examples/animation/sub-attaq/pics/big/submarine.png delete mode 100644 examples/animation/sub-attaq/pics/big/surface.png delete mode 100644 examples/animation/sub-attaq/pics/big/torpedo.png delete mode 100644 examples/animation/sub-attaq/pics/scalable/background-n810.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/background.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/boat.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/bomb.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/sand.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/see.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/sky.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/sub-attaq.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/submarine.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/surface.svg delete mode 100644 examples/animation/sub-attaq/pics/scalable/torpedo.svg delete mode 100644 examples/animation/sub-attaq/pics/small/background.png delete mode 100644 examples/animation/sub-attaq/pics/small/boat.png delete mode 100644 examples/animation/sub-attaq/pics/small/bomb.png delete mode 100644 examples/animation/sub-attaq/pics/small/submarine.png delete mode 100644 examples/animation/sub-attaq/pics/small/surface.png delete mode 100644 examples/animation/sub-attaq/pics/small/torpedo.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-a.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-a2.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-b.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-dash.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-excl.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-q.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-s.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-t.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-t2.png delete mode 100644 examples/animation/sub-attaq/pics/welcome/logo-u.png delete mode 100644 examples/animation/sub-attaq/pixmapitem.cpp delete mode 100644 examples/animation/sub-attaq/pixmapitem.h delete mode 100644 examples/animation/sub-attaq/progressitem.cpp delete mode 100644 examples/animation/sub-attaq/progressitem.h delete mode 100644 examples/animation/sub-attaq/qanimationstate.cpp delete mode 100644 examples/animation/sub-attaq/qanimationstate.h delete mode 100644 examples/animation/sub-attaq/states.cpp delete mode 100644 examples/animation/sub-attaq/states.h delete mode 100644 examples/animation/sub-attaq/sub-attaq.pro delete mode 100644 examples/animation/sub-attaq/subattaq.qrc delete mode 100644 examples/animation/sub-attaq/submarine.cpp delete mode 100644 examples/animation/sub-attaq/submarine.h delete mode 100644 examples/animation/sub-attaq/submarine_p.h delete mode 100644 examples/animation/sub-attaq/torpedo.cpp delete mode 100644 examples/animation/sub-attaq/torpedo.h delete mode 100644 examples/statemachine/README delete mode 100644 examples/statemachine/eventtransitions/eventtransitions.pro delete mode 100644 examples/statemachine/eventtransitions/main.cpp delete mode 100644 examples/statemachine/factorial/factorial.pro delete mode 100644 examples/statemachine/factorial/main.cpp delete mode 100644 examples/statemachine/pingpong/main.cpp delete mode 100644 examples/statemachine/pingpong/pingpong.pro delete mode 100644 examples/statemachine/statemachine.pro delete mode 100644 examples/statemachine/tankgame/gameitem.cpp delete mode 100644 examples/statemachine/tankgame/gameitem.h delete mode 100644 examples/statemachine/tankgame/gameovertransition.cpp delete mode 100644 examples/statemachine/tankgame/gameovertransition.h delete mode 100644 examples/statemachine/tankgame/main.cpp delete mode 100644 examples/statemachine/tankgame/mainwindow.cpp delete mode 100644 examples/statemachine/tankgame/mainwindow.h delete mode 100644 examples/statemachine/tankgame/plugin.h delete mode 100644 examples/statemachine/tankgame/rocketitem.cpp delete mode 100644 examples/statemachine/tankgame/rocketitem.h delete mode 100644 examples/statemachine/tankgame/tankgame.pro delete mode 100644 examples/statemachine/tankgame/tankitem.cpp delete mode 100644 examples/statemachine/tankgame/tankitem.h delete mode 100644 examples/statemachine/tankgameplugins/random_ai/random_ai.pro delete mode 100644 examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp delete mode 100644 examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h delete mode 100644 examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp delete mode 100644 examples/statemachine/tankgameplugins/seek_ai/seek_ai.h delete mode 100644 examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro delete mode 100644 examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp delete mode 100644 examples/statemachine/tankgameplugins/spin_ai/spin_ai.h delete mode 100644 examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro delete mode 100644 examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp delete mode 100644 examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h delete mode 100644 examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro delete mode 100644 examples/statemachine/tankgameplugins/tankgameplugins.pro delete mode 100644 examples/statemachine/trafficlight/main.cpp delete mode 100644 examples/statemachine/trafficlight/trafficlight.pro delete mode 100644 examples/statemachine/twowaybutton/main.cpp delete mode 100644 examples/statemachine/twowaybutton/twowaybutton.pro delete mode 100644 src/3rdparty/easing/easing.cpp delete mode 100644 src/3rdparty/easing/legal.qdoc delete mode 100644 src/corelib/animation/animation.pri delete mode 100644 src/corelib/animation/qabstractanimation.cpp delete mode 100644 src/corelib/animation/qabstractanimation.h delete mode 100644 src/corelib/animation/qabstractanimation_p.h delete mode 100644 src/corelib/animation/qanimationgroup.cpp delete mode 100644 src/corelib/animation/qanimationgroup.h delete mode 100644 src/corelib/animation/qanimationgroup_p.h delete mode 100644 src/corelib/animation/qparallelanimationgroup.cpp delete mode 100644 src/corelib/animation/qparallelanimationgroup.h delete mode 100644 src/corelib/animation/qparallelanimationgroup_p.h delete mode 100644 src/corelib/animation/qpauseanimation.cpp delete mode 100644 src/corelib/animation/qpauseanimation.h delete mode 100644 src/corelib/animation/qpropertyanimation.cpp delete mode 100644 src/corelib/animation/qpropertyanimation.h delete mode 100644 src/corelib/animation/qpropertyanimation_p.h delete mode 100644 src/corelib/animation/qsequentialanimationgroup.cpp delete mode 100644 src/corelib/animation/qsequentialanimationgroup.h delete mode 100644 src/corelib/animation/qsequentialanimationgroup_p.h delete mode 100644 src/corelib/animation/qvariantanimation.cpp delete mode 100644 src/corelib/animation/qvariantanimation.h delete mode 100644 src/corelib/animation/qvariantanimation_p.h delete mode 100644 src/corelib/statemachine/qabstractstate.cpp delete mode 100644 src/corelib/statemachine/qabstractstate.h delete mode 100644 src/corelib/statemachine/qabstractstate_p.h delete mode 100644 src/corelib/statemachine/qabstracttransition.cpp delete mode 100644 src/corelib/statemachine/qabstracttransition.h delete mode 100644 src/corelib/statemachine/qabstracttransition_p.h delete mode 100644 src/corelib/statemachine/qeventtransition.cpp delete mode 100644 src/corelib/statemachine/qeventtransition.h delete mode 100644 src/corelib/statemachine/qeventtransition_p.h delete mode 100644 src/corelib/statemachine/qfinalstate.cpp delete mode 100644 src/corelib/statemachine/qfinalstate.h delete mode 100644 src/corelib/statemachine/qhistorystate.cpp delete mode 100644 src/corelib/statemachine/qhistorystate.h delete mode 100644 src/corelib/statemachine/qhistorystate_p.h delete mode 100644 src/corelib/statemachine/qsignalevent.h delete mode 100644 src/corelib/statemachine/qsignaleventgenerator_p.h delete mode 100644 src/corelib/statemachine/qsignaltransition.cpp delete mode 100644 src/corelib/statemachine/qsignaltransition.h delete mode 100644 src/corelib/statemachine/qsignaltransition_p.h delete mode 100644 src/corelib/statemachine/qstate.cpp delete mode 100644 src/corelib/statemachine/qstate.h delete mode 100644 src/corelib/statemachine/qstate_p.h delete mode 100644 src/corelib/statemachine/qstatemachine.cpp delete mode 100644 src/corelib/statemachine/qstatemachine.h delete mode 100644 src/corelib/statemachine/qstatemachine_p.h delete mode 100644 src/corelib/statemachine/qwrappedevent.h delete mode 100644 src/corelib/statemachine/statemachine.pri delete mode 100644 src/corelib/tools/qeasingcurve.cpp delete mode 100644 src/corelib/tools/qeasingcurve.h delete mode 100644 src/gui/animation/animation.pri delete mode 100644 src/gui/animation/qguivariantanimation.cpp delete mode 100644 src/gui/statemachine/qbasickeyeventtransition.cpp delete mode 100644 src/gui/statemachine/qbasickeyeventtransition_p.h delete mode 100644 src/gui/statemachine/qbasicmouseeventtransition.cpp delete mode 100644 src/gui/statemachine/qbasicmouseeventtransition_p.h delete mode 100644 src/gui/statemachine/qguistatemachine.cpp delete mode 100644 src/gui/statemachine/qkeyeventtransition.cpp delete mode 100644 src/gui/statemachine/qkeyeventtransition.h delete mode 100644 src/gui/statemachine/qmouseeventtransition.cpp delete mode 100644 src/gui/statemachine/qmouseeventtransition.h delete mode 100644 src/gui/statemachine/statemachine.pri delete mode 100644 tests/auto/qanimationgroup/qanimationgroup.pro delete mode 100644 tests/auto/qanimationgroup/tst_qanimationgroup.cpp delete mode 100644 tests/auto/qeasingcurve/qeasingcurve.pro delete mode 100644 tests/auto/qeasingcurve/tst_qeasingcurve.cpp delete mode 100644 tests/auto/qparallelanimationgroup/qparallelanimationgroup.pro delete mode 100644 tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp delete mode 100644 tests/auto/qpropertyanimation/qpropertyanimation.pro delete mode 100644 tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp delete mode 100644 tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro delete mode 100644 tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp delete mode 100644 tests/auto/qstate/qstate.pro delete mode 100644 tests/auto/qstate/tst_qstate.cpp delete mode 100644 tests/auto/qstatemachine/qstatemachine.pro delete mode 100644 tests/auto/qstatemachine/tst_qstatemachine.cpp delete mode 100644 tests/benchmarks/qanimation/dummyanimation.cpp delete mode 100644 tests/benchmarks/qanimation/dummyanimation.h delete mode 100644 tests/benchmarks/qanimation/dummyobject.cpp delete mode 100644 tests/benchmarks/qanimation/dummyobject.h delete mode 100644 tests/benchmarks/qanimation/main.cpp delete mode 100644 tests/benchmarks/qanimation/qanimation.pro delete mode 100644 tests/benchmarks/qanimation/rectanimation.cpp delete mode 100644 tests/benchmarks/qanimation/rectanimation.h diff --git a/demos/qtdemo/xml/examples.xml b/demos/qtdemo/xml/examples.xml index 2560848..96a3e80 100644 --- a/demos/qtdemo/xml/examples.xml +++ b/demos/qtdemo/xml/examples.xml @@ -19,15 +19,6 @@ - - - - - - - - - @@ -176,12 +167,6 @@ - - - - - - diff --git a/doc/src/animation.qdoc b/doc/src/animation.qdoc deleted file mode 100644 index b4e603c..0000000 --- a/doc/src/animation.qdoc +++ /dev/null @@ -1,368 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page animation-overview.html - \title The Animation Framework - \ingroup architecture - \ingroup animation - \brief An overview of the Animation Framework - - \keyword Animation - - The animation framework is part of the Kinetic project, and aims - to provide an easy way for creating animated and smooth GUI's. By - animating Qt properties, the framework provides great freedom for - animating widgets and other \l{QObject}s. The framework can also - be used with the Graphics View framework. - - In this overview, we explain the basics of its architecture. We - also show examples of the most common techniques that the - framework allows for animating QObjects and graphics items. - - \tableofcontents - - \section1 The Animation Architecture - - We will in this section take a high-level look at the animation - framework's architecture and how it is used to animate Qt - properties. The following diagram shows the most important classes - in the animation framework. - - \image animations-architecture.png - - The animation framework foundation consists of the base class - QAbstractAnimation, and its two subclasses QVariantAnimation and - QAnimationGroup. QAbstractAnimation is the ancestor of all - animations. It represents basic properties that are common for all - animations in the framework; notably, the ability to start, stop, - and pause an animation. It is also receives the time change - notifications. - - The animation framework further provides the QPropertyAnimation - class, which inherits QVariantAnimation and performs animation of - a Qt property, which is part of Qt's \l{Meta-Object - System}{meta-object system}. The class performs an interpolation - over the property using an easing curve. So when you want to - animate a value, you can declare it as a property and make your - class a QObject. Note that this gives us great freedom in - animating already existing widgets and other \l{QObject}s. - - Complex animations can be constructed by building a tree structure - of \l{QAbstractAnimation}s. The tree is built by using - \l{QAnimationGroup}s, which function as containers for other - animations. Note also that the groups are subclasses of - QAbstractAnimation, so groups can themselves contain other groups. - - The animation framework can be used on its own, but is also - designed to be part of the state machine framework (See the - \l{The State Machine Framework}{state machine framework} for an - introduction to the Qt state machine). The state machine provides - a special state that can play an animation. A QState can also set - properties when the state is entered or exited, and this special - animation state will interpolate between these values when given a - QPropertyAnimation. We will look more closely at this later. - - Behind the scenes, the animations are controlled by a global - timer, which sends \l{QAbstractAnimation::updateCurrentTime()}{updates} to - all animations that are playing. - - For detailed descriptions of the classes' function and roles in - the framework, please look up their class descriptions. - - \section1 Animating Qt Properties - - As mentioned in the previous section, the QPropertyAnimation class - can interpolate over Qt properties. It is this class that should - be used for animation of values; in fact, its superclass, - QVariantAnimation, is an abstract class, and cannot be used - directly. - - A major reason we chose to animate Qt properties is that it - presents us with freedom to animate already existing classes in - the Qt API. Notably, the QWidget class (which we can also embed in - a QGraphicsView) has properties for its bounds, colors, etc. - Let's look at a small example: - - \code - QPushButton button("Animated Button"); - button.show(); - - QPropertyAnimation animation(&button, "geometry"); - animation.setDuration(10000); - animation.setStartValue(QRect(0, 0, 100, 30)); - animation.setEndValue(QRect(250, 250, 100, 30)); - - animation.start(); - \endcode - - This code will move \c button from the top left corner of the - screen to the position (250, 250) in 10 seconds (10000 milliseconds). - - The example above will do a linear interpolation between the - start and end value. It is also possible to set values - situated between the start and end value. The interpolation - will then go by these points. - - \code - QPushButton button("Animated Button"); - button.show(); - - QPropertyAnimation animation(&button, "geometry"); - animation.setDuration(10000); - - animation.setKeyValueAt(0, QRect(0, 0, 100, 30)); - animation.setKeyValueAt(0.8, QRect(250, 250, 100, 30)); - animation.setKeyValueAt(1, QRect(0, 0, 100, 30)); - - animation.start(); - \endcode - - In this example, the animation will take the button to (250, 250) - in 8 seconds, and then move it back to its original position in - the remaining 2 seconds. The movement will be linearly - interpolated between these points. - - You also have the possibility to animate values of a QObject - that is not declared as a Qt property. The only requirement is - that this value has a setter. You can then subclass the class - containing the value and declare a property that uses this setter. - Note that each Qt property requires a getter, so you will need to - provide a getter yourself if this is not defined. - - \code - class MyGraphicsRectItem : public QObject, public QGraphicsRectItem - { - Q_OBJECT - Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry) - }; - \endcode - - In the above code example, we subclass QGraphicsRectItem and - define a geometry property. We can now animate the widgets - geometry even if QGraphicsRectItem does not provide the geometry - property. - - For a general introduction to the Qt property system, see its - \l{Qt's Property System}{overview}. - - \section1 Animations and the Graphics View Framework - - When you want to animate \l{QGraphicsItem}s, you also use - QPropertyAnimation. However, QGraphicsItem does not inherit QObject. - A good solution is to subclass the graphics item you wish to animate. - This class will then also inherit QObject. - This way, QPropertyAnimation can be used for \l{QGraphicsItem}s. - The example below shows how this is done. Another possibility is - to inherit QGraphicsWidget, which already is a QObject. - - \code - class Pixmap : public QObject, public QGraphicsPixmapItem - { - Q_OBJECT - Q_PROPERTY(QPointF pos READ pos WRITE setPos) - ... - \endcode - - As described in the previous section, we need to define - properties that we wish to animate. - - Note that QObject must be the first class inherited as the - meta-object system demands this. - - \warning The QItemAnimation class, which was initially intended - for animating \l{QGraphicsItem}s may be deprecated or removed from - the animation framework. - - \omit (need something about the list of animations). \endomit - - \section1 Easing Curves - - As mentioned, QPropertyAnimation performs an interpolation between - the start and end property value. In addition to adding more key - values to the animation, you can also use an easing curve. Easing - curves describe a function that controls how the speed of the - interpolation between 0 and 1 should be, and are useful if you - want to control the speed of an animation without changing the - path of the interpolation. - - \code - QPushButton button("Animated Button"); - button.show(); - - QPropertyAnimation animation(&button, "geometry"); - animation.setDuration(3000); - animation.setStartValue(QRect(0, 0, 100, 30)); - animation.setEndValue(QRect(250, 250, 100, 30)); - - animation.setEasingCurve(QEasingCurve::OutBounce); - - animation.start(); - \endcode - - Here the animation will follow a curve that makes it bounce like a - ball as if it was dropped from the start to the end position. - QEasingCurve has a large collection of curves for you to choose - from. These are defined by the QEasingCurve::Type enum. If you are - in need of another curve, you can also implement one yourself, and - register it with QEasingCurve. - - \omit Drop this for the first Lab release - (Example of custom easing curve (without the actual impl of - the function I expect) - \endomit - - \section1 Putting Animations Together - - An application will often contain more than one animation. For - instance, you might want to move more than one graphics item - simultaneously or move them in sequence after each other. - - The subclasses of QAnimationGroup (QSequentialAnimationGroup and - QParallelAnimationGroup) are containers for other animations so - that these animations can be animated either in sequence or - parallel. The QAnimationGroup is an example of an animation that - does not animate properties, but it gets notified of time changes - periodically. This enables it to forward those time changes to its - contained animations, and thereby controlling when its animations - are played. - - Let's look at code examples that use both - QSequentialAnimationGroup and QParallelAnimationGroup, starting - off with the latter. - - \code - QPushButton *bonnie = new QPushButton("Bonnie"); - bonnie->show(); - - QPushButton *clyde = new QPushButton("Clyde"); - clyde->show(); - - QPropertyAnimation *anim1 = new QPropertyAnimation(bonnie, "geometry"); - // Set up anim1 - - QPropertyAnimation *anim2 = new QPropertyAnimation(clyde, "geometry"); - // Set up anim2 - - QParallelAnimationGroup *group = new QParallelAnimationGroup; - group->addAnimation(anim1); - group->addAnimation(anim2); - - group->start(); - \endcode - - A parallel group plays more than one animation at the same time. - Calling its \l{QAbstractAnimation::}{start()} function will start - all animations it governs. - - \code - QPushButton button("Animated Button"); - button.show(); - - QPropertyAnimation anim1(&button, "geometry"); - anim1.setDuration(3000); - anim1.setStartValue(QRect(0, 0, 100, 30)); - anim1.setEndValue(QRect(500, 500, 100, 30)); - - QPropertyAnimation anim2(&button, "geometry"); - anim2.setDuration(3000); - anim2.setStartValue(QRect(500, 500, 100, 30)); - anim2.setEndValue(QRect(1000, 500, 100, 30)); - - QSequentialAnimationGroup group; - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - - group.start(); - \endcode - - As you no doubt have guessed, QSequentialAnimationGroup plays - its animations in sequence. It starts the next animation in - the list after the previous is finished. - - Since an animation group is an animation itself, you can add - it to another group. This way, you can build a tree structure - of animations which specifies when the animations are played - in relation to each other. - - \section1 Animations and States - - When using a \l{The State Machine Framework}{state machine}, we - have a special state, QAnimationState, that will play one or more - animations. - - The QState::addAnimatedTransition() convenience function lets you - associate an animation to a state transition. The function will - create the QAnimationState for you, and insert it into the state - machine. We also have the possibility to associate properties with - the states rather than setting the start and end values ourselves. - Below is a complete code example that animates the geometry of a - QPushButton. - - \code - QPushButton *button = new QPushButton("Animated Button"); - button->show(); - - QStateMachine *machine = new QStateMachine; - - QState *state1 = new QState(machine->rootState()); - state1->setPropertyOnEntry(button, "geometry", - QRect(0, 0, 100, 30)); - machine->setInitialState(state1); - - QState *state2 = new QState(machine->rootState()); - state2->setPropertyOnEntry(button, "geometry", - QRect(250, 250, 100, 30)); - - state1->addAnimatedTransition(button, SIGNAL(clicked()), state2, - new QPropertyAnimation(button, "geometry")); - state2->addAnimatedTransition(button, SIGNAL(clicked()), state1, - new QPropertyAnimation(button, "geometry")); - - machine->start(); - \endcode - - For a more comprehensive example of how to use the state machine - framework for animations, see the states example (it lives in the - \c{examples/animation/states} directory). -*/ - diff --git a/doc/src/diagrams/animations-architecture.svg b/doc/src/diagrams/animations-architecture.svg deleted file mode 100644 index 0246510..0000000 --- a/doc/src/diagrams/animations-architecture.svg +++ /dev/null @@ -1,351 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - QAbstractAnimation - - QVariantAnimation - - QAnimationGroup - - - - QPropertyAnimation - - - QSequentialAnimationGroup - - QParallelAnimationGroup - - - - diff --git a/doc/src/diagrams/programs/easingcurve/easingcurve.pro b/doc/src/diagrams/programs/easingcurve/easingcurve.pro deleted file mode 100644 index 0b80127..0000000 --- a/doc/src/diagrams/programs/easingcurve/easingcurve.pro +++ /dev/null @@ -1,13 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) fr 13. feb 13:26:38 2009 -###################################################################### - -TEMPLATE = app -TARGET = -DEPENDPATH += . -INCLUDEPATH += . - -# Input -SOURCES += main.cpp - -CONFIG += console \ No newline at end of file diff --git a/doc/src/diagrams/programs/easingcurve/main.cpp b/doc/src/diagrams/programs/easingcurve/main.cpp deleted file mode 100644 index 98e9d37..0000000 --- a/doc/src/diagrams/programs/easingcurve/main.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the $MODULE$ of the Qt Toolkit. -** -** $TROLLTECH_DUAL_LICENSE$ -** -****************************************************************************/ - -#include - -void createCurveIcons(); - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - createCurveIcons(); - return app.exit(); -} - -void createCurveIcons() -{ - QDir dir(QDir::current()); - if (dir.dirName() == QLatin1String("debug") || dir.dirName() == QLatin1String("release")) { - dir.cdUp(); - } - dir.cdUp(); - dir.cdUp(); - dir.cdUp(); - QSize iconSize(128, 128); - QPixmap pix(iconSize); - QPainter painter(&pix); - QLinearGradient gradient(0,0, 0, iconSize.height()); - gradient.setColorAt(0.0, QColor(240, 240, 240)); - gradient.setColorAt(1.0, QColor(224, 224, 224)); - QBrush brush(gradient); - const QMetaObject &mo = QEasingCurve::staticMetaObject; - QMetaEnum metaEnum = mo.enumerator(mo.indexOfEnumerator("Type")); - QFont oldFont = painter.font(); - // Skip QEasingCurve::Custom - QString output(QString::fromAscii("%1/images").arg(dir.absolutePath())); - printf("Generating images to %s\n", qPrintable(output)); - for (int i = 0; i < QEasingCurve::NCurveTypes - 1; ++i) { - painter.setFont(oldFont); - QString name(QLatin1String(metaEnum.key(i))); - painter.fillRect(QRect(QPoint(0, 0), iconSize), brush); - QEasingCurve curve((QEasingCurve::Type)i); - painter.setPen(QColor(0, 0, 255, 64)); - qreal xAxis = iconSize.height()/1.5; - qreal yAxis = iconSize.width()/3; - painter.drawLine(0, xAxis, iconSize.width(), xAxis); // hor - painter.drawLine(yAxis, 0, yAxis, iconSize.height()); // ver - - qreal curveScale = iconSize.height()/2; - - painter.drawLine(yAxis - 2, xAxis - curveScale, yAxis + 2, xAxis - curveScale); // hor - painter.drawLine(yAxis + curveScale, xAxis + 2, yAxis + curveScale, xAxis - 2); // ver - painter.drawText(yAxis + curveScale - 8, xAxis - curveScale - 4, QLatin1String("(1,1)")); - - painter.drawText(yAxis + 42, xAxis + 10, QLatin1String("progress")); - painter.drawText(15, xAxis - curveScale - 10, QLatin1String("ease")); - - painter.setPen(QPen(Qt::red, 1, Qt::DotLine)); - painter.drawLine(yAxis, xAxis - curveScale, yAxis + curveScale, xAxis - curveScale); // hor - painter.drawLine(yAxis + curveScale, xAxis, yAxis + curveScale, xAxis - curveScale); // ver - - QPoint currentPos(yAxis, xAxis); - - painter.setPen(Qt::black); - QFont font = oldFont; - font.setPixelSize(oldFont.pixelSize() + 15); - painter.setFont(font); - painter.drawText(0, iconSize.height() - 20, iconSize.width(), 20, Qt::AlignHCenter, name); - - for (qreal t = 0; t < 1.0; t+=1.0/curveScale) { - QPoint to; - to.setX(yAxis + curveScale * t); - to.setY(xAxis - curveScale * curve.valueForProgress(t)); - painter.drawLine(currentPos, to); - currentPos = to; - } - QString fileName(QString::fromAscii("qeasingcurve-%1.png").arg(name.toLower())); - printf("%s\n", qPrintable(fileName)); - pix.save(QString::fromAscii("%1/%2").arg(output).arg(fileName), "PNG"); - } -} - - diff --git a/doc/src/examples-overview.qdoc b/doc/src/examples-overview.qdoc index 92ccd4e..549574d 100644 --- a/doc/src/examples-overview.qdoc +++ b/doc/src/examples-overview.qdoc @@ -319,14 +319,6 @@ from displaying Web pages within a Qt user interface to an implementation of a basic function Web browser. - \section1 \l{Qt Examples#State Machine}{State Machine} - - Qt provides a powerful hierchical finite state machine through the Qt State - Machine classes. - - These examples demonstrate the fundamental aspects of implementing - Statecharts with Qt. - \section1 \l{Qt Examples#Qt for Embedded Linux}{Qt for Embedded Linux} \l{Qt Examples#Qt for Embedded Linux}{\inlineimage qt-embedded-examples.png diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc index c55d29f..29c6c0b 100644 --- a/doc/src/examples.qdoc +++ b/doc/src/examples.qdoc @@ -86,12 +86,6 @@ \o \l{activeqt/webbrowser}{Web Browser}\raisedaster \o \l{activeqt/wrapper}{Wrapper}\raisedaster \endlist - - \section1 Animation - - \list - \o \l{animation/stickman}{Stick man}\raisedaster - \endlist \section1 Concurrent Programming @@ -314,17 +308,6 @@ \o \l{sql/sqlwidgetmapper}{SQL Widget Mapper}\raisedaster \endlist - \section1 State Machine - - \list - \o \l{statemachine/eventtransitions}{Event Transitions}\raisedaster - \o \l{statemachine/factorial}{Factorial States}\raisedaster - \o \l{statemachine/pingpong}{Ping Pong States}\raisedaster - \o \l{statemachine/trafficlight}{Traffic Light}\raisedaster - \o \l{statemachine/twowaybutton}{Two-way Button}\raisedaster - \o \l{statemachine/tankgame}{Tank Game}\raisedaster - \endlist - \section1 Threads \list diff --git a/doc/src/examples/eventtransitions.qdoc b/doc/src/examples/eventtransitions.qdoc deleted file mode 100644 index 3b956bb..0000000 --- a/doc/src/examples/eventtransitions.qdoc +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example statemachine/eventtransitions - \title Event Transitions Example - - The Event Transitions example shows how to use event transitions, a - feature of \l{The State Machine Framework}. - - \snippet examples/statemachine/eventtransitions/main.cpp 0 - - The \c Window class's constructors begins by creating a button. - - \snippet examples/statemachine/eventtransitions/main.cpp 1 - - Two states, \c s1 and \c s2, are created; upon entry they will assign - "Outside" and "Inside" to the button's text, respectively. - - \snippet examples/statemachine/eventtransitions/main.cpp 2 - - When the button receives an event of type QEvent::Enter and the state - machine is in state \c s1, the machine will transition to state \c s2. - - \snippet examples/statemachine/eventtransitions/main.cpp 3 - - When the button receives an event of type QEvent::Leave and the state - machine is in state \c s2, the machine will transition back to state \c - s1. - - \snippet examples/statemachine/eventtransitions/main.cpp 4 - - Next, the state \c s3 is created. \c s3 will be entered when the button - receives an event of type QEvent::MouseButtonPress and the state machine - is in state \c s2. When the button receives an event of type - QEvent::MouseButtonRelease and the state machine is in state \c s3, the - machine will transition back to state \c s2. - - \snippet examples/statemachine/eventtransitions/main.cpp 5 - - Finally, the states are added to the machine as top-level states, the - initial state is set to be \c s1 ("Outside"), and the machine is started. - - \snippet examples/statemachine/eventtransitions/main.cpp 6 - - The main() function constructs a Window object and shows it. - -*/ diff --git a/doc/src/examples/factorial.qdoc b/doc/src/examples/factorial.qdoc deleted file mode 100644 index 2a72e0a..0000000 --- a/doc/src/examples/factorial.qdoc +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example statemachine/factorial - \title Factorial States Example - - The Factorial States example shows how to use \l{The State Machine - Framework} to calculate the factorial of an integer. - - The statechart for calculating the factorial looks as follows: - - \img factorial-example.png - \omit - \caption This is a caption - \endomit - - In other words, the state machine calculates the factorial of 6 and prints - the result. - - \snippet examples/statemachine/factorial/main.cpp 0 - - The Factorial class is used to hold the data of the computation, \c x and - \c fac. It also provides a signal that's emitted whenever the value of \c - x changes. - - \snippet examples/statemachine/factorial/main.cpp 1 - - The FactorialLoopTransition class implements the guard (\c x > 1) and - calculations (\c fac = \c x * \c fac; \c x = \c x - 1) of the factorial - loop. - - \snippet examples/statemachine/factorial/main.cpp 2 - - The FactorialDoneTransition class implements the guard (\c x <= 1) that - terminates the factorial computation. It also prints the final result to - standard output. - - \snippet examples/statemachine/factorial/main.cpp 3 - - The application's main() function first creates the application object, a - Factorial object and a state machine. - - \snippet examples/statemachine/factorial/main.cpp 4 - - The \c compute state is created, and the initial values of \c x and \c fac - are defined. A FactorialLoopTransition object is created and added to the - state. - - \snippet examples/statemachine/factorial/main.cpp 5 - - A final state, \c done, is created, and a FactorialDoneTransition object - is created with \c done as its target state. The transition is then added - to the \c compute state. - - \snippet examples/statemachine/factorial/main.cpp 6 - - The machine's initial state is set to be the \c compute state. We connect - the QStateMachine::finished() signal to the QCoreApplication::quit() slot, - so the application will quit when the state machine's work is - done. Finally, the state machine is started, and the application's event - loop is entered. - - */ diff --git a/doc/src/examples/pingpong.qdoc b/doc/src/examples/pingpong.qdoc deleted file mode 100644 index 040e429..0000000 --- a/doc/src/examples/pingpong.qdoc +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example statemachine/pingpong - \title Ping Pong States Example - - The Ping Pong States example shows how to use parallel states together - with custom events and transitions in \l{The State Machine Framework}. - - This example implements a statechart where two states communicate by - posting events to the state machine. The state chart looks as follows: - - \img pingpong-example.png - \omit - \caption This is a caption - \endomit - - The \c pinger and \c ponger states are parallel states, i.e. they are - entered simultaneously and will take transitions independently of - eachother. - - The \c pinger state will post the first \c ping event upon entry; the \c - ponger state will respond by posting a \c pong event; this will cause the - \c pinger state to post a new \c ping event; and so on. - - \snippet examples/statemachine/pingpong/main.cpp 0 - - Two custom events are defined, \c PingEvent and \c PongEvent. - - \snippet examples/statemachine/pingpong/main.cpp 1 - - The \c Pinger class defines a state that posts a \c PingEvent to the state - machine when the state is entered. - - \snippet examples/statemachine/pingpong/main.cpp 2 - - The \c PingTransition class defines a transition that is triggered by - events of type \c PingEvent, and that posts a \c PongEvent (with a delay - of 500 milliseconds) to the state machine when the transition is - triggered. - - \snippet examples/statemachine/pingpong/main.cpp 3 - - The \c PongTransition class defines a transition that is triggered by - events of type \c PongEvent, and that posts a \c PingEvent (with a delay - of 500 milliseconds) to the state machine when the transition is - triggered. - - \snippet examples/statemachine/pingpong/main.cpp 4 - - The main() function begins by creating a state machine and a parallel - state group. - - \snippet examples/statemachine/pingpong/main.cpp 5 - - Next, the \c pinger and \c ponger states are created, with the parallel - state group as their parent state. Note that the transitions are \e - targetless. When such a transition is triggered, the source state won't be - exited and re-entered; only the transition's onTransition() function will - be called, and the state machine's configuration will remain the same, - which is precisely what we want in this case. - - \snippet examples/statemachine/pingpong/main.cpp 6 - - Finally, the group is added to the state machine, the machine is started, - and the application event loop is entered. - - */ diff --git a/doc/src/examples/stickman.qdoc b/doc/src/examples/stickman.qdoc deleted file mode 100644 index 49f4953..0000000 --- a/doc/src/examples/stickman.qdoc +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example animation/stickman - \title Stickman Example - - The Stickman example shows how to animate transitions in a state machine to implement key frame - animations. - - \image stickman-example.png - - In this example, we will write a small application which animates the joints in a skeleton and - projects a stickman figure on top. The stickman can be either "alive" or "dead", and when in the - "alive" state, he can be performing different actions defined by key frame animations. - - Animations are implemented as composite states. Each child state of the animation state - represents a frame in the animation by setting the position of each joint in the stickman's - skeleton to the positions defined for the particular frame. The frames are then bound together - with animated transitions that trigger on the source state's polished() signal. Thus, the - machine will enter the state representing the next frame in the animation immediately after it - has finished animating into the previous frame. - - \image stickman-example1.png - - The states for an animation is constructed by reading a custom animation file format and - creating states that assign values to the the "position" properties of each of the nodes in the - skeleton graph. - - \snippet examples/animation/stickman/lifecycle.cpp 1 - - The states are then bound together with signal transitions that listen to the polished() signal. - - \snippet examples/animation/stickman/lifecycle.cpp 2 - - The last frame state is given a transition to the first one, so that the animation will loop - until it is interrupted when a transition out from the animation state is taken. To get smooth - animations between the different key frames, we set a default animation on the state machine. - This is a parallel animation group which contains animations for all the "position" properties - and will be selected by default when taking any transition that leads into a state that assigns - values to these properties. - - \snippet examples/animation/stickman/lifecycle.cpp 3 - - Several such animation states are constructed, and are placed together as children of a top - level "alive" state which represents the stickman life cycle. Transitions go from the parent - state to the child state to ensure that each of the child states inherit them. - - \image stickman-example2.png - - This saves us the effort of connect every state to every state with identical transitions. The - state machine makes sure that transitions between the key frame animations are also smooth by - applying the default animation when interrupting one and starting another. - - Finally, there is a transition out from the "alive" state and into the "dead" state. This is - a custom transition type called LightningSrikesTransition which samples every second and - triggers at random (one out of fifty times on average.) - - \snippet examples/animation/stickman/lifecycle.cpp 4 - - When it triggers, the machine will first enter a "lightningBlink" state which uses a timer to - pause for a brief period of time while the background color of the scene is white. This gives us - a flash effect when the lightning strikes. - - \snippet examples/animation/stickman/lifecycle.cpp 5 - - We start and stop a QTimer object when entering and exiting the state. Then we transition into - the "dead" state when the timer times out. - - \snippet examples/animation/stickman/lifecycle.cpp 0 - - When the machine is in the "dead" state, it will be unresponsive. This is because the "dead" - state has no transitions leading out. - - \image stickman-example3.png - -*/ diff --git a/doc/src/examples/tankgame.qdoc b/doc/src/examples/tankgame.qdoc deleted file mode 100644 index ab3e0f4..0000000 --- a/doc/src/examples/tankgame.qdoc +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example statemachine/tankgame - \title Tank Game Example - - The Tank Game example is part of the in \l{The State Machine Framework}. It shows how to use - parallel states to implement artificial intelligence controllers that run in parallel, and error - states to handle run-time errors in parts of the state graph created by external plugins. - - \image tankgame-example.png - - In this example we write a simple game. The application runs a state machine with two main - states: A "stopped" state and a "running" state. The user can load plugins from the disk by - selecting the "Add tank" menu item. - - When the "Add tank" menu item is selected, the "plugins" subdirectory in the example's - directory is searched for compatible plugins. If any are found, they will be listed in a - dialog box created using QInputDialog::getItem(). - - \snippet examples/statemachine/tankgame/mainwindow.cpp 1 - - If the user selects a plugin, the application will construct a TankItem object, which inherits - from QGraphicsItem and QObject, and which implements an agreed-upon interface using the - meta-object mechanism. - - \snippet examples/statemachine/tankgame/tankitem.h 0 - - The tank item will be passed to the plugin's create() function. This will in turn return a - QState object which is expected to implement an artificial intelligence which controls the - tank and attempts to destroy other tanks it detects. - - \snippet examples/statemachine/tankgame/mainwindow.cpp 2 - - Each returned QState object becomes a descendant of a \c region in the "running" state, which is - defined as a parallel state. This means that entering the "running" state will cause each of the - plugged-in QState objects to be entered simultaneously, allowing the tanks to run independently - of each other. - - \snippet examples/statemachine/tankgame/mainwindow.cpp 0 - - The maximum number of tanks on the map is four, and when this number is reached, the - "Add tank" menu item should be disabled. This is implemented by giving the "stopped" state two - children which define whether the map is full or not. - - \snippet examples/statemachine/tankgame/mainwindow.cpp 5 - - To make sure that we go into the correct child state when returning from the "running" state - (if the "Stop game" menu item is selected while the game is running) we also give the "stopped" - state a history state which we make the initial state of "stopped" state. - - \snippet examples/statemachine/tankgame/mainwindow.cpp 3 - - Since part of the state graph is defined by external plugins, we have no way of controlling - whether they contain errors. By default, run-time errors are handled in the state machine by - entering a top level state which prints out an error message and never exits. If we were to - use this default behavior, a run-time error in any of the plugins would cause the "running" - state to exit, and thus all the other tanks to stop running as well. A better solution would - be if the broken plugin was disabled and the rest of the tanks allowed to continue as before. - - This is done by setting the error state of the plugin's top-most state to a special error state - defined specifically for the plugin in question. - - \snippet examples/statemachine/tankgame/mainwindow.cpp 4 - - If a run-time error occurs in \c pluginState or any of its descendants, the state machine will - search the hierarchy of ancestors until it finds a state whose error state is different from - \c null. (Note that if we are worried that a plugin could inadvertedly be overriding our - error state, we could search the descendants of \c pluginState and verify that their error - states are set to \c null before accepting the plugin.) - - The specialized \c errorState sets the "enabled" property of the tank item in question to false, - causing it to be painted with a red cross over it to indicate that it is no longer running. - Since the error state is a child of the same region in the parallel "running" state as - \c pluginState, it will not exit the "running" state, and the other tanks will continue running - without disruption. - -*/ diff --git a/doc/src/examples/trafficlight.qdoc b/doc/src/examples/trafficlight.qdoc deleted file mode 100644 index ae62127..0000000 --- a/doc/src/examples/trafficlight.qdoc +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example statemachine/trafficlight - \title Traffic Light Example - - The Traffic Light example shows how to use \l{The State Machine Framework} - to implement the control flow of a traffic light. - - \image trafficlight-example.png - - In this example we write a TrafficLightWidget class. The traffic light has - three lights: Red, yellow and green. The traffic light transitions from - one light to another (red to yellow to green to yellow to red again) at - certain intervals. - - \snippet examples/statemachine/trafficlight/main.cpp 0 - - The LightWidget class represents a single light of the traffic light. It - provides an \c on property and two slots, turnOn() and turnOff(), to turn - the light on and off, respectively. The widget paints itself in the color - that's passed to the constructor. - - \snippet examples/statemachine/trafficlight/main.cpp 1 - - The TrafficLightWidget class represents the visual part of the traffic - light; it's a widget that contains three lights arranged vertically, and - provides accessor functions for these. - - \snippet examples/statemachine/trafficlight/main.cpp 2 - - The createLightState() function creates a state that turns a light on when - the state is entered, and off when the state is exited. The state uses a - timer, and as we shall see the timeout is used to transition from one - LightState to another. Here is the statechart for the light state: - - \img trafficlight-example1.png - \omit - \caption This is a caption - \endomit - - \snippet examples/statemachine/trafficlight/main.cpp 3 - - The TrafficLight class combines the TrafficLightWidget with a state - machine. The state graph has four states: red-to-yellow, yellow-to-green, - green-to-yellow and yellow-to-red. The initial state is red-to-yellow; - when the state's timer times out, the state machine transitions to - yellow-to-green. The same process repeats through the other states. - This is what the statechart looks like: - - \img trafficlight-example2.png - \omit - \caption This is a caption - \endomit - - \snippet examples/statemachine/trafficlight/main.cpp 4 - - The main() function constructs a TrafficLight and shows it. - -*/ diff --git a/doc/src/examples/twowaybutton.qdoc b/doc/src/examples/twowaybutton.qdoc deleted file mode 100644 index 87de2e8..0000000 --- a/doc/src/examples/twowaybutton.qdoc +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example statemachine/twowaybutton - \title Two-way Button Example - - The Two-way button example shows how to use \l{The State Machine - Framework} to implement a simple state machine that toggles the current - state when a button is clicked. - - \snippet examples/statemachine/twowaybutton/main.cpp 0 - - The application's main() function begins by constructing the application - object, a button and a state machine. - - \snippet examples/statemachine/twowaybutton/main.cpp 1 - - The state machine has two states; \c on and \c off. When either state is - entered, the text of the button will be set accordingly. - - \snippet examples/statemachine/twowaybutton/main.cpp 2 - - When the state machine is in the \c off state and the button is clicked, - it will transition to the \c on state; when the state machine is in the \c - on state and the button is clicked, it will transition to the \c off - state. - - \snippet examples/statemachine/twowaybutton/main.cpp 3 - - The states are added to the state machine; they become top-level (sibling) - states. - - \snippet examples/statemachine/twowaybutton/main.cpp 4 - - The initial state is \c off; this is the state the state machine will - immediately transition to once the state machine is started. - - \snippet examples/statemachine/twowaybutton/main.cpp 5 - - Finally, the button is resized and made visible, and the application event - loop is entered. - -*/ diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc index 3bfb5af..f48c3d7 100644 --- a/doc/src/external-resources.qdoc +++ b/doc/src/external-resources.qdoc @@ -334,16 +334,6 @@ */ /*! - \externalpage http://www.w3.org/TR/scxml/ - \title State Chart XML: State Machine Notation for Control Abstraction -*/ - -/*! - \externalpage http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Statecharts.pdf - \title Statecharts: A visual formalism for complex systems -*/ - -/*! \externalpage http://www.gnu.org/licenses/gpl.html \title GNU General Public License */ diff --git a/doc/src/groups.qdoc b/doc/src/groups.qdoc index 3c4da53..c9cedc4 100644 --- a/doc/src/groups.qdoc +++ b/doc/src/groups.qdoc @@ -69,18 +69,6 @@ */ /*! - \group animation - \ingroup groups - - \title Animation Framework - \brief Classes for animations, states and transitions. - - These classes provide a framework for creating both simple and complex - animations. \l{The Animation Framework} also provides states and animated - transitions, making it easy to create animated stateful forms. -*/ - -/*! \group abstractwidgets \title Abstract Widget Classes \ingroup groups @@ -609,14 +597,3 @@ These classes are relevant to developers who are working with Qt Script's debugging features. */ - -/*! - \group statemachine - \ingroup groups - - \title State Machine Classes - \brief Classes for constructing and executing state graphs. - - These classes are provided by \l{The State Machine Framework} for creating - event-driven state machines. -*/ diff --git a/doc/src/images/animations-architecture.png b/doc/src/images/animations-architecture.png deleted file mode 100644 index 9b581af..0000000 Binary files a/doc/src/images/animations-architecture.png and /dev/null differ diff --git a/doc/src/images/factorial-example.png b/doc/src/images/factorial-example.png deleted file mode 100644 index 8fb1cc6..0000000 Binary files a/doc/src/images/factorial-example.png and /dev/null differ diff --git a/doc/src/images/pingpong-example.png b/doc/src/images/pingpong-example.png deleted file mode 100644 index af707e4..0000000 Binary files a/doc/src/images/pingpong-example.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-cosinecurve.png b/doc/src/images/qeasingcurve-cosinecurve.png deleted file mode 100644 index b27e763..0000000 Binary files a/doc/src/images/qeasingcurve-cosinecurve.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inback.png b/doc/src/images/qeasingcurve-inback.png deleted file mode 100644 index 8506c0f..0000000 Binary files a/doc/src/images/qeasingcurve-inback.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inbounce.png b/doc/src/images/qeasingcurve-inbounce.png deleted file mode 100644 index 275b38c..0000000 Binary files a/doc/src/images/qeasingcurve-inbounce.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-incirc.png b/doc/src/images/qeasingcurve-incirc.png deleted file mode 100644 index b985e9c..0000000 Binary files a/doc/src/images/qeasingcurve-incirc.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-incubic.png b/doc/src/images/qeasingcurve-incubic.png deleted file mode 100644 index e417ee1..0000000 Binary files a/doc/src/images/qeasingcurve-incubic.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-incurve.png b/doc/src/images/qeasingcurve-incurve.png deleted file mode 100644 index d9a9340..0000000 Binary files a/doc/src/images/qeasingcurve-incurve.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inelastic.png b/doc/src/images/qeasingcurve-inelastic.png deleted file mode 100644 index b242fd3..0000000 Binary files a/doc/src/images/qeasingcurve-inelastic.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inexpo.png b/doc/src/images/qeasingcurve-inexpo.png deleted file mode 100644 index f06316c..0000000 Binary files a/doc/src/images/qeasingcurve-inexpo.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutback.png b/doc/src/images/qeasingcurve-inoutback.png deleted file mode 100644 index 9fd1446..0000000 Binary files a/doc/src/images/qeasingcurve-inoutback.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutbounce.png b/doc/src/images/qeasingcurve-inoutbounce.png deleted file mode 100644 index fb65f31..0000000 Binary files a/doc/src/images/qeasingcurve-inoutbounce.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutcirc.png b/doc/src/images/qeasingcurve-inoutcirc.png deleted file mode 100644 index 123cc54..0000000 Binary files a/doc/src/images/qeasingcurve-inoutcirc.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutcubic.png b/doc/src/images/qeasingcurve-inoutcubic.png deleted file mode 100644 index b07695c..0000000 Binary files a/doc/src/images/qeasingcurve-inoutcubic.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutelastic.png b/doc/src/images/qeasingcurve-inoutelastic.png deleted file mode 100644 index 65851e1..0000000 Binary files a/doc/src/images/qeasingcurve-inoutelastic.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutexpo.png b/doc/src/images/qeasingcurve-inoutexpo.png deleted file mode 100644 index 7cbfb13..0000000 Binary files a/doc/src/images/qeasingcurve-inoutexpo.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutquad.png b/doc/src/images/qeasingcurve-inoutquad.png deleted file mode 100644 index c5eed06..0000000 Binary files a/doc/src/images/qeasingcurve-inoutquad.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutquart.png b/doc/src/images/qeasingcurve-inoutquart.png deleted file mode 100644 index 3b66c0d..0000000 Binary files a/doc/src/images/qeasingcurve-inoutquart.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutquint.png b/doc/src/images/qeasingcurve-inoutquint.png deleted file mode 100644 index c74efe9..0000000 Binary files a/doc/src/images/qeasingcurve-inoutquint.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inoutsine.png b/doc/src/images/qeasingcurve-inoutsine.png deleted file mode 100644 index 5964f31..0000000 Binary files a/doc/src/images/qeasingcurve-inoutsine.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inquad.png b/doc/src/images/qeasingcurve-inquad.png deleted file mode 100644 index 3373310..0000000 Binary files a/doc/src/images/qeasingcurve-inquad.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inquart.png b/doc/src/images/qeasingcurve-inquart.png deleted file mode 100644 index 28086d8..0000000 Binary files a/doc/src/images/qeasingcurve-inquart.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-inquint.png b/doc/src/images/qeasingcurve-inquint.png deleted file mode 100644 index 330aa85..0000000 Binary files a/doc/src/images/qeasingcurve-inquint.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-insine.png b/doc/src/images/qeasingcurve-insine.png deleted file mode 100644 index 63d9238..0000000 Binary files a/doc/src/images/qeasingcurve-insine.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-linear.png b/doc/src/images/qeasingcurve-linear.png deleted file mode 100644 index 2a05885..0000000 Binary files a/doc/src/images/qeasingcurve-linear.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outback.png b/doc/src/images/qeasingcurve-outback.png deleted file mode 100644 index 7cb34c6..0000000 Binary files a/doc/src/images/qeasingcurve-outback.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outbounce.png b/doc/src/images/qeasingcurve-outbounce.png deleted file mode 100644 index 932fc16..0000000 Binary files a/doc/src/images/qeasingcurve-outbounce.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outcirc.png b/doc/src/images/qeasingcurve-outcirc.png deleted file mode 100644 index a1a6cb6..0000000 Binary files a/doc/src/images/qeasingcurve-outcirc.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outcubic.png b/doc/src/images/qeasingcurve-outcubic.png deleted file mode 100644 index aa1d604..0000000 Binary files a/doc/src/images/qeasingcurve-outcubic.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outcurve.png b/doc/src/images/qeasingcurve-outcurve.png deleted file mode 100644 index a949ae4..0000000 Binary files a/doc/src/images/qeasingcurve-outcurve.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outelastic.png b/doc/src/images/qeasingcurve-outelastic.png deleted file mode 100644 index 2a9ba39..0000000 Binary files a/doc/src/images/qeasingcurve-outelastic.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outexpo.png b/doc/src/images/qeasingcurve-outexpo.png deleted file mode 100644 index e771c2e..0000000 Binary files a/doc/src/images/qeasingcurve-outexpo.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outinback.png b/doc/src/images/qeasingcurve-outinback.png deleted file mode 100644 index 7523727..0000000 Binary files a/doc/src/images/qeasingcurve-outinback.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outinbounce.png b/doc/src/images/qeasingcurve-outinbounce.png deleted file mode 100644 index ab73d02..0000000 Binary files a/doc/src/images/qeasingcurve-outinbounce.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outincirc.png b/doc/src/images/qeasingcurve-outincirc.png deleted file mode 100644 index ec4b8d3..0000000 Binary files a/doc/src/images/qeasingcurve-outincirc.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outincubic.png b/doc/src/images/qeasingcurve-outincubic.png deleted file mode 100644 index 8b8ae68..0000000 Binary files a/doc/src/images/qeasingcurve-outincubic.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outinelastic.png b/doc/src/images/qeasingcurve-outinelastic.png deleted file mode 100644 index 89dde2c..0000000 Binary files a/doc/src/images/qeasingcurve-outinelastic.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outinexpo.png b/doc/src/images/qeasingcurve-outinexpo.png deleted file mode 100644 index 5909901..0000000 Binary files a/doc/src/images/qeasingcurve-outinexpo.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outinquad.png b/doc/src/images/qeasingcurve-outinquad.png deleted file mode 100644 index 7ddefee..0000000 Binary files a/doc/src/images/qeasingcurve-outinquad.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outinquart.png b/doc/src/images/qeasingcurve-outinquart.png deleted file mode 100644 index 00ef597..0000000 Binary files a/doc/src/images/qeasingcurve-outinquart.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outinquint.png b/doc/src/images/qeasingcurve-outinquint.png deleted file mode 100644 index 361bfaa4..0000000 Binary files a/doc/src/images/qeasingcurve-outinquint.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outinsine.png b/doc/src/images/qeasingcurve-outinsine.png deleted file mode 100644 index 1737041..0000000 Binary files a/doc/src/images/qeasingcurve-outinsine.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outquad.png b/doc/src/images/qeasingcurve-outquad.png deleted file mode 100644 index 6f27cbd..0000000 Binary files a/doc/src/images/qeasingcurve-outquad.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outquart.png b/doc/src/images/qeasingcurve-outquart.png deleted file mode 100644 index d45a0b8..0000000 Binary files a/doc/src/images/qeasingcurve-outquart.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outquint.png b/doc/src/images/qeasingcurve-outquint.png deleted file mode 100644 index 6e7df0e..0000000 Binary files a/doc/src/images/qeasingcurve-outquint.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-outsine.png b/doc/src/images/qeasingcurve-outsine.png deleted file mode 100644 index 7546a0d..0000000 Binary files a/doc/src/images/qeasingcurve-outsine.png and /dev/null differ diff --git a/doc/src/images/qeasingcurve-sinecurve.png b/doc/src/images/qeasingcurve-sinecurve.png deleted file mode 100644 index ca67d44..0000000 Binary files a/doc/src/images/qeasingcurve-sinecurve.png and /dev/null differ diff --git a/doc/src/images/statemachine-button-history.png b/doc/src/images/statemachine-button-history.png deleted file mode 100644 index 7f51cae..0000000 Binary files a/doc/src/images/statemachine-button-history.png and /dev/null differ diff --git a/doc/src/images/statemachine-button-nested.png b/doc/src/images/statemachine-button-nested.png deleted file mode 100644 index 762ac14..0000000 Binary files a/doc/src/images/statemachine-button-nested.png and /dev/null differ diff --git a/doc/src/images/statemachine-button.png b/doc/src/images/statemachine-button.png deleted file mode 100644 index 10102bd..0000000 Binary files a/doc/src/images/statemachine-button.png and /dev/null differ diff --git a/doc/src/images/statemachine-customevents.png b/doc/src/images/statemachine-customevents.png deleted file mode 100644 index 62a4222..0000000 Binary files a/doc/src/images/statemachine-customevents.png and /dev/null differ diff --git a/doc/src/images/statemachine-customevents2.png b/doc/src/images/statemachine-customevents2.png deleted file mode 100644 index 57b37ef..0000000 Binary files a/doc/src/images/statemachine-customevents2.png and /dev/null differ diff --git a/doc/src/images/statemachine-finished.png b/doc/src/images/statemachine-finished.png deleted file mode 100644 index 0ac081d..0000000 Binary files a/doc/src/images/statemachine-finished.png and /dev/null differ diff --git a/doc/src/images/statemachine-nonparallel.png b/doc/src/images/statemachine-nonparallel.png deleted file mode 100644 index f9850a7..0000000 Binary files a/doc/src/images/statemachine-nonparallel.png and /dev/null differ diff --git a/doc/src/images/statemachine-parallel.png b/doc/src/images/statemachine-parallel.png deleted file mode 100644 index a65c297..0000000 Binary files a/doc/src/images/statemachine-parallel.png and /dev/null differ diff --git a/doc/src/images/stickman-example.png b/doc/src/images/stickman-example.png deleted file mode 100644 index a40f37b..0000000 Binary files a/doc/src/images/stickman-example.png and /dev/null differ diff --git a/doc/src/images/stickman-example1.png b/doc/src/images/stickman-example1.png deleted file mode 100644 index 1596a68..0000000 Binary files a/doc/src/images/stickman-example1.png and /dev/null differ diff --git a/doc/src/images/stickman-example2.png b/doc/src/images/stickman-example2.png deleted file mode 100644 index 980276a..0000000 Binary files a/doc/src/images/stickman-example2.png and /dev/null differ diff --git a/doc/src/images/stickman-example3.png b/doc/src/images/stickman-example3.png deleted file mode 100644 index 3635ff7..0000000 Binary files a/doc/src/images/stickman-example3.png and /dev/null differ diff --git a/doc/src/images/tankgame-example.png b/doc/src/images/tankgame-example.png deleted file mode 100644 index 9e17e30..0000000 Binary files a/doc/src/images/tankgame-example.png and /dev/null differ diff --git a/doc/src/images/trafficlight-example.png b/doc/src/images/trafficlight-example.png deleted file mode 100644 index 3431542..0000000 Binary files a/doc/src/images/trafficlight-example.png and /dev/null differ diff --git a/doc/src/images/trafficlight-example1.png b/doc/src/images/trafficlight-example1.png deleted file mode 100644 index ec8c7ff..0000000 Binary files a/doc/src/images/trafficlight-example1.png and /dev/null differ diff --git a/doc/src/images/trafficlight-example2.png b/doc/src/images/trafficlight-example2.png deleted file mode 100644 index a12e4db..0000000 Binary files a/doc/src/images/trafficlight-example2.png and /dev/null differ diff --git a/doc/src/snippets/animation/sequential/icons.qrc b/doc/src/snippets/animation/sequential/icons.qrc deleted file mode 100644 index d55f797..0000000 --- a/doc/src/snippets/animation/sequential/icons.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - icons/left.png - icons/right.png - - diff --git a/doc/src/snippets/animation/sequential/icons/left.png b/doc/src/snippets/animation/sequential/icons/left.png deleted file mode 100644 index 5dd8da0..0000000 Binary files a/doc/src/snippets/animation/sequential/icons/left.png and /dev/null differ diff --git a/doc/src/snippets/animation/sequential/icons/right.png b/doc/src/snippets/animation/sequential/icons/right.png deleted file mode 100644 index ac61326..0000000 Binary files a/doc/src/snippets/animation/sequential/icons/right.png and /dev/null differ diff --git a/doc/src/snippets/animation/sequential/main.cpp b/doc/src/snippets/animation/sequential/main.cpp deleted file mode 100644 index aff8f29..0000000 --- a/doc/src/snippets/animation/sequential/main.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include -#include -#include "tracer.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - QWidget window; - window.resize(720, 96); - window.show(); - - QLabel *label1 = new QLabel(&window); - label1->setPixmap(QPixmap(":/icons/left.png")); - label1->move(16, 16); - label1->show(); - - QLabel *label2 = new QLabel(&window); - label2->setPixmap(QPixmap(":/icons/right.png")); - label2->move(320, 16); - label2->show(); - - QPropertyAnimation *anim1 = new QPropertyAnimation(label1, "pos"); - anim1->setDuration(2500); - anim1->setStartValue(QPoint(16, 16)); - anim1->setEndValue(QPoint(320, 16)); - - QPropertyAnimation *anim2 = new QPropertyAnimation(label2, "pos"); - anim2->setDuration(2500); - anim2->setStartValue(QPoint(320, 16)); - anim2->setEndValue(QPoint(640, 16)); - - QSequentialAnimationGroup group; - group.addAnimation(anim1); - group.addAnimation(anim2); - - Tracer tracer(&window); - - QObject::connect(anim1, SIGNAL(valueChanged(QVariant)), - &tracer, SLOT(recordValue(QVariant))); - QObject::connect(anim2, SIGNAL(valueChanged(QVariant)), - &tracer, SLOT(recordValue(QVariant))); - QObject::connect(anim1, SIGNAL(finished()), &tracer, SLOT(checkValue())); - QObject::connect(anim2, SIGNAL(finished()), &tracer, SLOT(checkValue())); - - group.start(); - return app.exec(); -} diff --git a/doc/src/snippets/animation/sequential/sequential.pro b/doc/src/snippets/animation/sequential/sequential.pro deleted file mode 100644 index fcf017f..0000000 --- a/doc/src/snippets/animation/sequential/sequential.pro +++ /dev/null @@ -1,4 +0,0 @@ -HEADERS = tracer.h -RESOURCES = icons.qrc -SOURCES = main.cpp \ - tracer.cpp diff --git a/doc/src/snippets/animation/sequential/tracer.cpp b/doc/src/snippets/animation/sequential/tracer.cpp deleted file mode 100644 index 49bd51e..0000000 --- a/doc/src/snippets/animation/sequential/tracer.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include "tracer.h" - -Tracer::Tracer(QObject *parent) - : QObject(parent) -{ -} - -void Tracer::checkValue() -{ - QAbstractAnimation *animation = static_cast(sender()); - if (time != animation->duration()) { - qDebug() << "Animation's last recorded time" << time; - qDebug() << "Expected" << animation->duration(); - } -} - -void Tracer::recordValue(const QVariant &value) -{ - QAbstractAnimation *animation = static_cast(sender()); - this->value = value; - time = animation->currentTime(); -} diff --git a/doc/src/snippets/animation/sequential/tracer.h b/doc/src/snippets/animation/sequential/tracer.h deleted file mode 100644 index 1adb018..0000000 --- a/doc/src/snippets/animation/sequential/tracer.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TRACER_H -#define TRACER_H - -#include -#include - -class Tracer : public QObject -{ - Q_OBJECT - -public: - Tracer(QObject *parent = 0); - -public slots: - void checkValue(); - void recordValue(const QVariant &value); - -private: - QVariant value; - int time; -}; - -#endif diff --git a/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp b/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp deleted file mode 100644 index 65358ea..0000000 --- a/doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp +++ /dev/null @@ -1,4 +0,0 @@ -//! [0] -qreal myEasingFunction(qreal progress); -//! [0] - diff --git a/doc/src/statemachine.qdoc b/doc/src/statemachine.qdoc deleted file mode 100644 index 5a89f4d..0000000 --- a/doc/src/statemachine.qdoc +++ /dev/null @@ -1,645 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \page statemachine-api.html - \title The State Machine Framework - \brief An overview of the State Machine framework for constructing and executing state graphs. - \ingroup architecture - - \tableofcontents - - The State Machine framework provides classes for creating and executing - state graphs. The concepts and notation are based on those from Harel's - \l{Statecharts: A visual formalism for complex systems}{Statecharts}, which - is also the basis of UML state diagrams. The semantics of state machine - execution are based on \l{State Chart XML: State Machine Notation for - Control Abstraction}{State Chart XML (SCXML)}. - - Statecharts provide a graphical way of modeling how a system reacts to - stimuli. This is done by defining the possible \e states that the system can - be in, and how the system can move from one state to another (\e transitions - between states). A key characteristic of event-driven systems (such as Qt - applications) is that behavior often depends not only on the last or current - event, but also the events that preceded it. With statecharts, this - information is easy to express. - - The State Machine framework provides an API and execution model that can be - used to effectively embed the elements and semantics of statecharts in Qt - applications. The framework integrates tightly with Qt's meta-object system; - for example, transitions between states can be triggered by signals, and - states can be configured to set properties and invoke methods on QObjects. - Qt's event system is used to drive the state machines. - - \section1 A Simple State Machine - - To demonstrate the core functionality of the State Machine API, let's look - at a small example: A state machine with three states, \c s1, \c s2 and \c - s3. The state machine is controlled by a single QPushButton; when the button - is clicked, the machine transitions to another state. Initially, the state - machine is in state \c s1. The statechart for this machine is as follows: - - \img statemachine-button.png - \omit - \caption This is a caption - \endomit - - The following snippet shows the code needed to create such a state machine. - First, we create the state machine and states: - - \code - QStateMachine machine; - QState *s1 = new QState(); - QState *s2 = new QState(); - QState *s3 = new QState(); - \endcode - - Then, we create the transitions by using the QState::addTransition() - function: - - \code - s1->addTransition(button, SIGNAL(clicked()), s2); - s2->addTransition(button, SIGNAL(clicked()), s3); - s3->addTransition(button, SIGNAL(clicked()), s1); - \endcode - - Next, we add the states to the machine and set the machine's initial state: - - \code - machine.addState(s1); - machine.addState(s2); - machine.addState(s3); - machine.setInitialState(s1); - \endcode - - Finally, we start the state machine: - - \code - machine.start(); - \endcode - - The state machine executes asynchronously, i.e. it becomes part of your - application's event loop. - - \section1 Doing Useful Work on State Entry and Exit - - The above state machine merely transitions from one state to another, it - doesn't perform any operations. The QState::assignProperty() function can be - used to have a state set a property of a QObject when the state is - entered. In the following snippet, the value that should be assigned to a - QLabel's text property is specified for each state: - - \code - s1->assignProperty(label, "text", "In state s1"); - s2->assignProperty(label, "text", "In state s2"); - s3->assignProperty(label, "text", "In state s3"); - \endcode - - When any of the states is entered, the label's text will be changed - accordingly. - - The QState::entered() signal is emitted when the state is entered, and the - QState::exited() signal is emitted when the state is exited. In the - following snippet, the button's showMaximized() slot will be called when - state \c s3 is entered, and the button's showMinimized() slot will be called - when \c s3 is exited: - - \code - QObject::connect(s3, SIGNAL(entered()), button, SLOT(showMaximized())); - QObject::connect(s3, SIGNAL(exited()), button, SLOT(showMinimized())); - \endcode - - Custom states can reimplement QAbstractState::onEntry() and - QAbstractState::onExit(). - - \section1 State Machines That Finish - - The state machine defined in the previous section never finishes. In order - for a state machine to be able to finish, it needs to have a top-level \e - final state (QFinalState object). When the state machine enters a top-level - final state, the machine will emit the QStateMachine::finished() signal and - halt. - - All you need to do to introduce a final state in the graph is create a - QFinalState object and use it as the target of one or more transitions. - - \section1 Sharing Transitions By Grouping States - - Assume we wanted the user to be able to quit the application at any time by - clicking a Quit button. In order to achieve this, we need to create a final - state and make it the target of a transition associated with the Quit - button's clicked() signal. We could add a transition from each of \c s1, \c - s2 and \c s3; however, this seems redundant, and one would also have to - remember to add such a transition from every new state that is added in the - future. - - We can achieve the same behavior (namely that clicking the Quit button quits - the state machine, regardless of which state the state machine is in) by - grouping states \c s1, \c s2 and \c s3. This is done by creating a new - top-level state and making the three original states children of the new - state. The following diagram shows the new state machine. - - \img statemachine-button-nested.png - \omit - \caption This is a caption - \endomit - - The three original states have been renamed \c s11, \c s12 and \c s13 to - reflect that they are now children of the new top-level state, \c s1. Child - states implicitly inherit the transitions of their parent state. This means - it is now sufficient to add a single transition from \c s1 to the final - state \c s2. New states added to \c s1 will also automatically inherit this - transition. - - All that's needed to group states is to specify the proper parent when the - state is created. You also need to specify which of the child states is the - initial one (i.e. which child state the state machine should enter when the - parent state is the target of a transition). - - \code - QState *s1 = new QState(); - QState *s11 = new QState(s1); - QState *s12 = new QState(s1); - QState *s13 = new QState(s1); - s1->setInitialState(s11); - machine.addState(s1); - \endcode - - \code - QFinalState *s2 = new QFinalState(); - s1->addTransition(quitButton, SIGNAL(clicked()), s2); - machine.addState(s2); - - QObject::connect(&machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit())); - \endcode - - In this case we want the application to quit when the state machine is - finished, so the machine's finished() signal is connected to the - application's quit() slot. - - A child state can override an inherited transition. For example, the - following code adds a transition that effectively causes the Quit button to - be ignored when the state machine is in state \c s12. - - \code - s12>addTransition(quitButton, SIGNAL(clicked()), s12); - \endcode - - A transition can have any state as its target, i.e. the target state does - not have to be on the same level in the state hierarchy as the source state. - - \section1 Using History States to Save and Restore the Current State - - Imagine that we wanted to add an "interrupt" mechanism to the example - discussed in the previous section; the user should be able to click a button - to have the state machine perform some non-related task, after which the - state machine should resume whatever it was doing before (i.e. return to the - old state, which is one of \c s11, \c s12 and \c s13 in this case). - - Such behavior can easily be modeled using \e{history states}. A history - state (QHistoryState object) is a pseudo-state that represents the child - state that the parent state was in the last time the parent state was - exited. - - A history state is created as a child of the state for which we wish to - record the current child state; when the state machine detects the presence - of such a state at runtime, it automatically records the current (real) - child state when the parent state is exited. A transition to the history - state is in fact a transition to the child state that the state machine had - previously saved; the state machine automatically "forwards" the transition - to the real child state. - - The following diagram shows the state machine after the interrupt mechanism - has been added. - - \img statemachine-button-history.png - \omit - \caption This is a caption - \endomit - - The following code shows how it can be implemented; in this example we - simply display a message box when \c s3 is entered, then immediately return - to the previous child state of \c s1 via the history state. - - \code - QHistoryState *s1h = s1->addHistoryState(); - - QState *s3 = new QState(); - s3->assignProperty(label, "text", "In s3"); - QMessageBox mbox; - mbox.addButton(QMessageBox::Ok); - mbox.setText("Interrupted!"); - mbox.setIcon(QMessageBox::Information); - QObject::connect(s3, SIGNAL(entered()), &mbox, SLOT(exec())); - s3->addTransition(s1h); - machine.addState(s3); - - s1->addTransition(interruptButton, SIGNAL(clicked()), s3); - \endcode - - \section1 Using Parallel States to Avoid a Combinatorial Explosion of States - - Assume that you wanted to model a set of mutually exclusive properties of a - car in a single state machine. Let's say the properties we are interested in - are Clean vs Dirty, and Moving vs Not moving. It would take four mutually - exclusive states and eight transitions to be able to represent and freely - move between all possible combinations. - - \img statemachine-nonparallel.png - \omit - \caption This is a caption - \endomit - - If we added a third property (say, Red vs Blue), the total number of states - would double, to eight; and if we added a fourth property (say, Enclosed vs - Convertible), the total number of states would double again, to 16. - - Using parallel states, the total number of states and transitions grows - linearly as we add more properties, instead of exponentially. Furthermore, - states can be added to or removed from the parallel state without affecting - any of their sibling states. - - \img statemachine-parallel.png - \omit - \caption This is a caption - \endomit - - To create a parallel state group, pass QState::ParallelStates to the QState - constructor. - - \code - QState *s1 = new QState(QState::ParallelStates); - // s11 and s12 will be entered in parallel - QState *s11 = new QState(s1); - QState *s12 = new QState(s1); - \endcode - - When a parallel state group is entered, all its child states will be - simultaneously entered. Transitions within the individual child states - operate normally. However, any of the child states may take a transition - outside the parent state. When this happens, the parent state and all of its - child states are exited. - - \section1 Detecting that a Composite State has Finished - - A child state can be final (a QFinalState object); when a final child state - is entered, the parent state emits the QState::finished() signal. The - following diagram shows a composite state \c s1 which does some processing - before entering a final state: - - \img statemachine-finished.png - \omit - \caption This is a caption - \endomit - - When \c s1 's final state is entered, \c s1 will automatically emit - finished(). We use a signal transition to cause this event to trigger a - state change: - - \code - s1->addTransition(s1, SIGNAL(finished()), s2); - \endcode - - Using final states in composite states is useful when you want to hide the - internal details of a composite state; i.e. the only thing the outside world - should be able to do is enter the state, and get a notification when the - state has completed its work. This is a very powerful abstraction and - encapsulation mechanism when building complex (deeply nested) state - machines. (In the above example, you could of course create a transition - directly from \c s1 's \c done state rather than relying on \c s1 's - finished() signal, but with the consequence that implementation details of - \c s1 are exposed and depended on). - - For parallel state groups, the QState::finished() signal is emitted when \e - all the child states have entered final states. - - \section1 Events, Transitions and Guards - - A QStateMachine runs its own event loop. For signal transitions - (QSignalTransition objects), QStateMachine automatically posts a - QSignalEvent to itself when it intercepts the corresponding signal; - similarly, for QObject event transitions (QEventTransition objects) a - QWrappedEvent is posted. - - You can post your own events to the state machine using - QStateMachine::postEvent(). - - When posting a custom event to the state machine, you typically also have - one or more custom transitions that can be triggered from events of that - type. To create such a transition, you subclass QAbstractTransition and - reimplement QAbstractTransition::eventTest(), where you check if an event - matches your event type (and optionally other criteria, e.g. attributes of - the event object). - - Here we define our own custom event type, \c StringEvent, for posting - strings to the state machine: - - \code - struct StringEvent : public QEvent - { - StringEvent(const QString &val) - : QEvent(QEvent::Type(QEvent::User+1)), - value(val) {} - - QString value; - }; - \endcode - - Next, we define a transition that only triggers when the event's string - matches a particular string (a \e guarded transition): - - \code - class StringTransition : public QAbstractTransition - { - public: - StringTransition(const QString &value) - : m_value(value) {} - - protected: - virtual bool eventTest(QEvent *e) const - { - if (e->type() != QEvent::Type(QEvent::User+1)) // StringEvent - return false; - StringEvent *se = static_cast(e); - return (m_value == se->value); - } - - virtual void onTransition(QEvent *) {} - - private: - QString m_value; - }; - \endcode - - In the eventTest() reimplementation, we first check if the event type is the - desired one; if so, we cast the event to a StringEvent and perform the - string comparison. - - The following is a statechart that uses the custom event and transition: - - \img statemachine-customevents.png - \omit - \caption This is a caption - \endomit - - Here's what the implementation of the statechart looks like: - - \code - QStateMachine machine; - QState *s1 = new QState(); - QState *s2 = new QState(); - QFinalState *done = new QFinalState(); - - StringTransition *t1 = new StringTransition("Hello"); - t1->setTargetState(s2); - s1->addTransition(t1); - StringTransition *t2 = new StringTransition("world"); - t2->setTargetState(done); - s2->addTransition(t2); - - machine.addState(s1); - machine.addState(s2); - machine.addState(done); - machine.setInitialState(s1); - \endcode - - Once the machine is started, we can post events to it. - - \code - machine.postEvent(new StringEvent("Hello")); - machine.postEvent(new StringEvent("world")); - \endcode - - An event that is not handled by any relevant transition will be silently - consumed by the state machine. It can be useful to group states and provide - a default handling of such events; for example, as illustrated in the - following statechart: - - \img statemachine-customevents2.png - \omit - \caption This is a caption - \endomit - - For deeply nested statecharts, you can add such "fallback" transitions at - the level of granularity that's most appropriate. - - \section1 Using Restore Policy To Automatically Restore Properties - - In some state machines it can be useful to focus the attention on assigning properties in states, - not on restoring them when the state is no longer active. If you know that a property should - always be restored to its initial value when the machine enters a state that does not explicitly - give the property a value, you can set the global restore policy to - QStateMachine::RestoreProperties. - - \code - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - \endcode - - When this restore policy is set, the machine will automatically restore all properties. If it - enters a state where a given property is not set, it will first search the hierarchy of ancestors - to see if the property is defined there. If it is, the property will be restored to the value - defined by the closest ancestor. If not, it will be restored to its initial value (i.e. the - value of the property before any property assignments in states were executed.) - - Take the following code: - \code - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - - QState *s1 = new QState(); - s1->assignProperty(object, "fooBar", 1.0); - machine.addState(s1); - machine.setInitialState(s1); - - QState *s2 = new QState(); - machine.addState(s2); - \endcode - - Lets say the property \c fooBar is 0.0 when the machine starts. When the machine is in state - \c s1, the property will be 1.0, since the state explicitly assigns this value to it. When the - machine is in state \c s2, no value is explicitly defined for the property, so it will implicitly - be restored to 0.0. - - If we are using nested states, the parent defines a value for the property which is inherited by - all descendants that do not explicitly assign a value to the property. - \code - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - - QState *s1 = new QState(); - s1->assignProperty(object, "fooBar", 1.0); - machine.addState(s1); - machine.setInitialState(s1); - - QState *s2 = new QState(s1); - s2->assignProperty(object, "fooBar", 2.0); - s1->setInitialState(s2); - - QState *s3 = new QState(s1); - \endcode - - Here \c s1 has two children: \c s2 and \c s3. When \c s2 is entered, the property \c fooBar - will have the value 2.0, since this is explicitly defined for the state. When the machine is in - state \c s3, no value is defined for the state, but \c s1 defines the property to be 1.0, so this - is the value that will be assigned to \c fooBar. - - \section1 Animating Property Assignments - - The State Machine API connects with the Animation API in Qt to allow automatically animating - properties as they are assigned in states. - - Say we have the following code: - \code - QState *s1 = new QState(); - QState *s2 = new QState(); - - s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); - s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100)); - - s1->addTransition(button, SIGNAL(clicked()), s2); - \endcode - - Here we define two states of a user interface. In \c s1 the \c button is small, and in \c s2 - it is bigger. If we click the button to transition from \c s1 to \c s2, the geometry of the button - will be set immediately when a given state has been entered. If we want the transition to be - smooth, however, all we need to do is make a QPropertyAnimation and add this to the transition - object. - - \code - QState *s1 = new QState(); - QState *s2 = new QState(); - - s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); - s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100)); - - QSignalTransition *transition = s1->addTransition(button, SIGNAL(clicked()), s2); - transition->addAnimation(new QPropertyAnimation(button, "geometry")); - \endcode - - Adding an animation for the property in question means that the property assignment will no - longer take immediate effect when the state has been entered. Instead, the animation will start - playing when the state has been entered and smoothly animate the property assignment. Since we - do not set the start value or end value of the animation, these will be set implicitly. The - start value of the animation will be the property's current value when the animation starts, and - the end value will be set based on the property assignments defined for the state. - - If the global restore policy of the state machine is set to QStateMachine::RestoreProperties, - it is possible to also add animations for the property restorations. - - \section1 Detecting That All Properties Have Been Set In A State - - When animations are used to assign properties, a state no longer defines the exact values that a - property will have when the machine is in the given state. While the animation is running, the - property can potentially have any value, depending on the animation. - - In some cases, it can be useful to be able to detect when the property has actually been assigned - the value defined by a state. For this, we can use the state's polished() signal. - \code - QState *s1 = new QState(); - s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); - - QState *s2 = new QState(); - - s1->addTransition(s1, SIGNAL(polished()), s2); - \endcode - - The machine will be in state \c s1 until the \c geometry property has been set. Then it will - immediately transition into \c s2. If the transition into \c s1 has an animation for the \c - geometry property, then the machine will stay in \c s1 until the animation has finished. If there - is no animation, it will simply set the property and immediately enter state \c s2. - - Either way, when the machine is in state \c s2, the property \c geometry has been assigned the - defined value. - - If the global restore policy is set to QStateMachine::RestoreProperties, the state will not emit - the polished() signal until these have been executed as well. - - \section1 What happens if a state is exited before the animation has finished - - If a state has property assignments, and the transition into the state has animations for the - properties, the state can potentially be exited before the properties have been assigned to the - values defines by the state. This is true in particular when there are transitions out from the - state that do not depend on the state being polished, as described in the previous section. - - The State Machine API guarantees that a property assigned by the state machine either: - \list - \o Has a value explicitly assigned to the property. - \o Is currently being animated into a value explicitly assigned to the property. - \endlist - - When a state is exited prior to the animation finishing, the behavior of the state machine depends - on the target state of the transition. If the target state explicitly assigns a value to the - property, no additional action will be taken. The property will be assigned the value defined by - the target state. - - If the target state does not assign any value to the property, there are two - options: By default, the property will be assigned the value defined by the state it is leaving - (the value it would have been assigned if the animation had been permitted to finish playing.) If - a global restore policy is set, however, this will take precedence, and the property will be - restored as usual. - - \section1 Default Animations - - As described earlier, you can add animations to transitions to make sure property assignments - in the target state are animated. If you want a specific animation to be used for a given property - regardless of which transition is taken, you can add it as a default animation to the state - machine. This is in particular useful when the properties assigned (or restored) by specific - states is not known when the machine is constructed. - - \code - QState *s1 = new QState(); - QState *s2 = new QState(); - - s2->assignProperty(object, "fooBar", 2.0); - s1->addTransition(s2); - - QStateMachine machine; - machine.setInitialState(s1); - machine.addDefaultAnimation(new QPropertyAnimation(object, "fooBar")); - \endcode - - When the machine is in state \c s2, the machine will play the default animation for the - property \c fooBar since this property is assigned by \c s2. - - Note that animations explicitly set on transitions will take precedence over any default - animation for the given property. -*/ diff --git a/examples/animation/README b/examples/animation/README deleted file mode 100644 index 6a892f8..0000000 --- a/examples/animation/README +++ /dev/null @@ -1,38 +0,0 @@ -The animation framework aims to provide an easy way for creating animated and -smooth GUI's. By animating Qt properties, the framework provides great freedom -for animating widgets and other QObjects. The framework can also be used with -the Graphics View framework. - -The example launcher provided with Qt can be used to explore each of the -examples in this directory. - -Documentation for these examples can be found via the Tutorial and Examples -link in the main Qt documentation. - - -Finding the Qt Examples and Demos launcher -========================================== - -On Windows: - -The launcher can be accessed via the Windows Start menu. Select the menu -entry entitled "Qt Examples and Demos" entry in the submenu containing -the Qt tools. - -On Mac OS X: - -For the binary distribution, the qtdemo executable is installed in the -/Developer/Applications/Qt directory. For the source distribution, it is -installed alongside the other Qt tools on the path specified when Qt is -configured. - -On Unix/Linux: - -The qtdemo executable is installed alongside the other Qt tools on the path -specified when Qt is configured. - -On all platforms: - -The source code for the launcher can be found in the demos/qtdemo directory -in the Qt package. This example is built at the same time as the Qt libraries, -tools, examples, and demonstrations. diff --git a/examples/animation/animatedtiles/animatedtiles.pro b/examples/animation/animatedtiles/animatedtiles.pro deleted file mode 100644 index 1840b17..0000000 --- a/examples/animation/animatedtiles/animatedtiles.pro +++ /dev/null @@ -1,8 +0,0 @@ -SOURCES = main.cpp -RESOURCES = animatedtiles.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/animation/animatedtiles -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS animatedtiles.pro images -sources.path = $$[QT_INSTALL_EXAMPLES]/animation/animatedtiles -INSTALLS += target sources diff --git a/examples/animation/animatedtiles/animatedtiles.qrc b/examples/animation/animatedtiles/animatedtiles.qrc deleted file mode 100644 index c43a979..0000000 --- a/examples/animation/animatedtiles/animatedtiles.qrc +++ /dev/null @@ -1,11 +0,0 @@ - - - images/Time-For-Lunch-2.jpg - images/centered.png - images/ellipse.png - images/figure8.png - images/kinetic.png - images/random.png - images/tile.png - - diff --git a/examples/animation/animatedtiles/images/Time-For-Lunch-2.jpg b/examples/animation/animatedtiles/images/Time-For-Lunch-2.jpg deleted file mode 100644 index c57a555..0000000 Binary files a/examples/animation/animatedtiles/images/Time-For-Lunch-2.jpg and /dev/null differ diff --git a/examples/animation/animatedtiles/images/centered.png b/examples/animation/animatedtiles/images/centered.png deleted file mode 100644 index e416156..0000000 Binary files a/examples/animation/animatedtiles/images/centered.png and /dev/null differ diff --git a/examples/animation/animatedtiles/images/ellipse.png b/examples/animation/animatedtiles/images/ellipse.png deleted file mode 100644 index 2c3ba88..0000000 Binary files a/examples/animation/animatedtiles/images/ellipse.png and /dev/null differ diff --git a/examples/animation/animatedtiles/images/figure8.png b/examples/animation/animatedtiles/images/figure8.png deleted file mode 100644 index 6b05804..0000000 Binary files a/examples/animation/animatedtiles/images/figure8.png and /dev/null differ diff --git a/examples/animation/animatedtiles/images/kinetic.png b/examples/animation/animatedtiles/images/kinetic.png deleted file mode 100644 index 55cfa55..0000000 Binary files a/examples/animation/animatedtiles/images/kinetic.png and /dev/null differ diff --git a/examples/animation/animatedtiles/images/random.png b/examples/animation/animatedtiles/images/random.png deleted file mode 100644 index 415d96f..0000000 Binary files a/examples/animation/animatedtiles/images/random.png and /dev/null differ diff --git a/examples/animation/animatedtiles/images/tile.png b/examples/animation/animatedtiles/images/tile.png deleted file mode 100644 index c8f39d8..0000000 Binary files a/examples/animation/animatedtiles/images/tile.png and /dev/null differ diff --git a/examples/animation/animatedtiles/main.cpp b/examples/animation/animatedtiles/main.cpp deleted file mode 100644 index 4b1d99d..0000000 --- a/examples/animation/animatedtiles/main.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -class Pixmap : public QObject, public QGraphicsPixmapItem -{ - Q_OBJECT - Q_PROPERTY(QPointF pos READ pos WRITE setPos) -public: - Pixmap(const QPixmap &pix) - : QObject(), QGraphicsPixmapItem(pix) - { - setCacheMode(DeviceCoordinateCache); - } -}; - -class Button : public QGraphicsWidget -{ - Q_OBJECT -public: - Button(const QPixmap &pixmap, QGraphicsItem *parent = 0) - : QGraphicsWidget(parent), _pix(pixmap) - { - setAcceptHoverEvents(true); - setCacheMode(DeviceCoordinateCache); - } - - QRectF boundingRect() const - { - return QRectF(-65, -65, 130, 130); - } - - QPainterPath shape() const - { - QPainterPath path; - path.addEllipse(boundingRect()); - return path; - } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) - { - bool down = option->state & QStyle::State_Sunken; - QRectF r = boundingRect(); - QLinearGradient grad(r.topLeft(), r.bottomRight()); - grad.setColorAt(down ? 1 : 0, option->state & QStyle::State_MouseOver ? Qt::white : Qt::lightGray); - grad.setColorAt(down ? 0 : 1, Qt::darkGray); - painter->setPen(Qt::darkGray); - painter->setBrush(grad); - painter->drawEllipse(r); - QLinearGradient grad2(r.topLeft(), r.bottomRight()); - grad.setColorAt(down ? 1 : 0, Qt::darkGray); - grad.setColorAt(down ? 0 : 1, Qt::lightGray); - painter->setPen(Qt::NoPen); - painter->setBrush(grad); - if (down) - painter->translate(2, 2); - painter->drawEllipse(r.adjusted(5, 5, -5, -5)); - painter->drawPixmap(-_pix.width()/2, -_pix.height()/2, _pix); - } - -signals: - void pressed(); - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent *) - { - emit pressed(); - update(); - } - - void mouseReleaseEvent(QGraphicsSceneMouseEvent *) - { - update(); - } - -private: - QPixmap _pix; -}; - -class View : public QGraphicsView -{ -public: - View(QGraphicsScene *scene) : QGraphicsView(scene) { } - -protected: - void resizeEvent(QResizeEvent *event) - { - QGraphicsView::resizeEvent(event); - fitInView(sceneRect(), Qt::KeepAspectRatio); - } -}; - -int main(int argc, char **argv) -{ - Q_INIT_RESOURCE(animatedtiles); - - QApplication app(argc, argv); - - QPixmap kineticPix(":/images/kinetic.png"); - QPixmap bgPix(":/images/Time-For-Lunch-2.jpg"); - - QGraphicsScene scene(-350, -350, 700, 700); - - QList items; - for (int i = 0; i < 64; ++i) { - Pixmap *item = new Pixmap(kineticPix); - item->setOffset(-kineticPix.width()/2, -kineticPix.height()/2); - item->setZValue(i); - items << item; - scene.addItem(item); - } - - // Buttons - QGraphicsItem *buttonParent = new QGraphicsRectItem; - Button *ellipseButton = new Button(QPixmap(":/images/ellipse.png"), buttonParent); - Button *figure8Button = new Button(QPixmap(":/images/figure8.png"), buttonParent); - Button *randomButton = new Button(QPixmap(":/images/random.png"), buttonParent); - Button *tiledButton = new Button(QPixmap(":/images/tile.png"), buttonParent); - Button *centeredButton = new Button(QPixmap(":/images/centered.png"), buttonParent); - - ellipseButton->setPos(-100, -100); - figure8Button->setPos(100, -100); - randomButton->setPos(0, 0); - tiledButton->setPos(-100, 100); - centeredButton->setPos(100, 100); - - scene.addItem(buttonParent); - buttonParent->scale(0.75, 0.75); - buttonParent->setPos(200, 200); - buttonParent->setZValue(65); - - // States - QState *rootState = new QState; - QState *ellipseState = new QState(rootState); - QState *figure8State = new QState(rootState); - QState *randomState = new QState(rootState); - QState *tiledState = new QState(rootState); - QState *centeredState = new QState(rootState); - - // Values - for (int i = 0; i < 64; ++i) { - Pixmap *item = items.at(i); - // Ellipse - ellipseState->assignProperty(item, "pos", - QPointF(cos((i / 63.0) * 6.28) * 250, - sin((i / 63.0) * 6.28) * 250)); - - // Figure 8 - figure8State->assignProperty(item, "pos", - QPointF(sin((i / 63.0) * 6.28) * 250, - sin(((i * 2)/63.0) * 6.28) * 250)); - - // Random - randomState->assignProperty(item, "pos", - QPointF(-250 + qrand() % 500, - -250 + qrand() % 500)); - - // Tiled - tiledState->assignProperty(item, "pos", - QPointF(((i % 8) - 4) * kineticPix.width() + kineticPix.width() / 2, - ((i / 8) - 4) * kineticPix.height() + kineticPix.height() / 2)); - - // Centered - centeredState->assignProperty(item, "pos", QPointF()); - } - - // Ui - View *view = new View(&scene); - view->setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Animated Tiles")); - view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); - view->setBackgroundBrush(bgPix); - view->setCacheMode(QGraphicsView::CacheBackground); - view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - view->show(); - - QStateMachine states; - states.addState(rootState); - states.setInitialState(rootState); - rootState->setInitialState(centeredState); - - QParallelAnimationGroup *group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { - QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); - anim->setDuration(750 + i * 25); - anim->setEasingCurve(QEasingCurve::InOutBack); - group->addAnimation(anim); - } - QAbstractTransition *trans = rootState->addTransition(ellipseButton, SIGNAL(pressed()), ellipseState); - trans->addAnimation(group); - - group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { - QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); - anim->setDuration(750 + i * 25); - anim->setEasingCurve(QEasingCurve::InOutBack); - group->addAnimation(anim); - } - trans = rootState->addTransition(figure8Button, SIGNAL(pressed()), figure8State); - trans->addAnimation(group); - - group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { - QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); - anim->setDuration(750 + i * 25); - anim->setEasingCurve(QEasingCurve::InOutBack); - group->addAnimation(anim); - } - trans = rootState->addTransition(randomButton, SIGNAL(pressed()), randomState); - trans->addAnimation(group); - - group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { - QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); - anim->setDuration(750 + i * 25); - anim->setEasingCurve(QEasingCurve::InOutBack); - group->addAnimation(anim); - } - trans = rootState->addTransition(tiledButton, SIGNAL(pressed()), tiledState); - trans->addAnimation(group); - - group = new QParallelAnimationGroup; - for (int i = 0; i < 64; ++i) { - QPropertyAnimation *anim = new QPropertyAnimation(items[i], "pos"); - anim->setDuration(750 + i * 25); - anim->setEasingCurve(QEasingCurve::InOutBack); - group->addAnimation(anim); - } - trans = rootState->addTransition(centeredButton, SIGNAL(pressed()), centeredState); - trans->addAnimation(group); - - states.start(); - QTimer timer; - timer.start(125); - timer.setSingleShot(true); - rootState->addTransition(&timer, SIGNAL(timeout()), ellipseState); - - return app.exec(); -} - -#include "main.moc" diff --git a/examples/animation/animation.pro b/examples/animation/animation.pro deleted file mode 100644 index 9a2874b..0000000 --- a/examples/animation/animation.pro +++ /dev/null @@ -1,16 +0,0 @@ -TEMPLATE = \ - subdirs -SUBDIRS += \ - animatedtiles \ - appchooser \ - easing \ - moveblocks \ - states \ - stickman \ - sub-attaq - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/animation -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS animation.pro README -sources.path = $$[QT_INSTALL_EXAMPLES]/animation -INSTALLS += target sources diff --git a/examples/animation/appchooser/accessories-dictionary.png b/examples/animation/appchooser/accessories-dictionary.png deleted file mode 100644 index e9bd55d..0000000 Binary files a/examples/animation/appchooser/accessories-dictionary.png and /dev/null differ diff --git a/examples/animation/appchooser/akregator.png b/examples/animation/appchooser/akregator.png deleted file mode 100644 index a086f45..0000000 Binary files a/examples/animation/appchooser/akregator.png and /dev/null differ diff --git a/examples/animation/appchooser/appchooser.pro b/examples/animation/appchooser/appchooser.pro deleted file mode 100644 index 847b60a..0000000 --- a/examples/animation/appchooser/appchooser.pro +++ /dev/null @@ -1,8 +0,0 @@ -SOURCES = main.cpp -RESOURCES = appchooser.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/animation/appchooser -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS appchooser.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/animation/appchooser -INSTALLS += target sources diff --git a/examples/animation/appchooser/appchooser.qrc b/examples/animation/appchooser/appchooser.qrc deleted file mode 100644 index 28a3e1c..0000000 --- a/examples/animation/appchooser/appchooser.qrc +++ /dev/null @@ -1,8 +0,0 @@ - - - accessories-dictionary.png - akregator.png - digikam.png - k3b.png - - diff --git a/examples/animation/appchooser/digikam.png b/examples/animation/appchooser/digikam.png deleted file mode 100644 index 9de9fb2..0000000 Binary files a/examples/animation/appchooser/digikam.png and /dev/null differ diff --git a/examples/animation/appchooser/k3b.png b/examples/animation/appchooser/k3b.png deleted file mode 100644 index bbcafcf..0000000 Binary files a/examples/animation/appchooser/k3b.png and /dev/null differ diff --git a/examples/animation/appchooser/main.cpp b/examples/animation/appchooser/main.cpp deleted file mode 100644 index 44457f7..0000000 --- a/examples/animation/appchooser/main.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - - -class Pixmap : public QGraphicsWidget -{ - Q_OBJECT - -public: - Pixmap(const QPixmap &pix, QGraphicsItem *parent = 0) - : QGraphicsWidget(parent), orig(pix), p(pix) - { - } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) - { - painter->drawPixmap(QPointF(), p); - } - - virtual void mousePressEvent(QGraphicsSceneMouseEvent * ) - { - emit clicked(); - } - - virtual void setGeometry(const QRectF &rect) - { - QGraphicsWidget::setGeometry(rect); - - if (rect.size().width() > orig.size().width()) - p = orig.scaled(rect.size().toSize()); - else - p = orig; - } - -Q_SIGNALS: - void clicked(); - -private: - QPixmap orig; - QPixmap p; -}; - -void createStates(const QObjectList &objects, - const QRect &selectedRect, QState *parent) -{ - for (int i = 0; i < objects.size(); ++i) { - QState *state = new QState(parent); - state->assignProperty(objects.at(i), "geometry", selectedRect); - parent->addTransition(objects.at(i), SIGNAL(clicked()), state); - } -} - -void createAnimations(const QObjectList &objects, QStateMachine *machine) -{ - for (int i=0; iaddDefaultAnimation(new QPropertyAnimation(objects.at(i), "geometry")); -} - -int main(int argc, char **argv) -{ - Q_INIT_RESOURCE(appchooser); - - QApplication app(argc, argv); - - Pixmap *p1 = new Pixmap(QPixmap(":/digikam.png")); - Pixmap *p2 = new Pixmap(QPixmap(":/akregator.png")); - Pixmap *p3 = new Pixmap(QPixmap(":/accessories-dictionary.png")); - Pixmap *p4 = new Pixmap(QPixmap(":/k3b.png")); - - p1->setObjectName("p1"); - p2->setObjectName("p2"); - p3->setObjectName("p3"); - p4->setObjectName("p4"); - - p1->setGeometry(QRectF(0.0, 0.0, 64.0, 64.0)); - p2->setGeometry(QRectF(236.0, 0.0, 64.0, 64.0)); - p3->setGeometry(QRectF(236.0, 236.0, 64.0, 64.0)); - p4->setGeometry(QRectF(0.0, 236.0, 64.0, 64.0)); - - QGraphicsScene scene(0, 0, 300, 300); - scene.setBackgroundBrush(Qt::white); - scene.addItem(p1); - scene.addItem(p2); - scene.addItem(p3); - scene.addItem(p4); - - QGraphicsView window(&scene); - window.setFrameStyle(0); - window.setAlignment(Qt::AlignLeft | Qt::AlignTop); - window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - - QState *group = new QState(machine.rootState()); - group->setObjectName("group"); - QRect selectedRect(86, 86, 128, 128); - - QState *idleState = new QState(group); - group->setInitialState(idleState); - - QObjectList objects; - objects << p1 << p2 << p3 << p4; - createStates(objects, selectedRect, group); - createAnimations(objects, &machine); - - machine.setInitialState(group); - machine.start(); - - window.resize(300, 300); - window.show(); - - return app.exec(); -} - -#include "main.moc" diff --git a/examples/animation/easing/animation.h b/examples/animation/easing/animation.h deleted file mode 100644 index d4d699d..0000000 --- a/examples/animation/easing/animation.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANIMATION_H -#define ANIMATION_H - -#include - -#include - -class Animation : public QPropertyAnimation { -public: - enum PathType { - LinearPath, - CirclePath, - NPathTypes - }; - Animation(QObject *target, const QByteArray &prop) - : QPropertyAnimation(target, prop) - { - setPathType(LinearPath); - } - - void setPathType(PathType pathType) - { - if (pathType >= NPathTypes) - qWarning("Unknown pathType %d", pathType); - - m_pathType = pathType; - m_path = QPainterPath(); - } - - void updateCurrentTime(int msecs) - { - if (m_pathType == CirclePath) { - if (m_path.isEmpty()) { - QPointF to = endValue().toPointF(); - QPointF from = startValue().toPointF(); - m_path.moveTo(from); - m_path.addEllipse(QRectF(from, to)); - } - int dura = duration(); - const qreal progress = ((dura == 0) ? 1 : ((((currentTime() - 1) % dura) + 1) / qreal(dura))); - - qreal easedProgress = easingCurve().valueForProgress(progress); - if (easedProgress > 1.0) { - easedProgress -= 1.0; - } else if (easedProgress < 0) { - easedProgress += 1.0; - } - QPointF pt = m_path.pointAtPercent(easedProgress); - updateCurrentValue(pt); - emit valueChanged(pt); - } else { - QPropertyAnimation::updateCurrentTime(msecs); - } - } - - QPainterPath m_path; - PathType m_pathType; -}; - -#endif // ANIMATION_H diff --git a/examples/animation/easing/easing.pro b/examples/animation/easing/easing.pro deleted file mode 100644 index 8e8a35f..0000000 --- a/examples/animation/easing/easing.pro +++ /dev/null @@ -1,14 +0,0 @@ -HEADERS = window.h \ - animation.h -SOURCES = main.cpp \ - window.cpp - -FORMS = form.ui - -RESOURCES = easing.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/animation/easing -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS easing.pro images -sources.path = $$[QT_INSTALL_EXAMPLES]/animation/easing -INSTALLS += target sources diff --git a/examples/animation/easing/easing.qrc b/examples/animation/easing/easing.qrc deleted file mode 100644 index 7e112d3..0000000 --- a/examples/animation/easing/easing.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - images/qt-logo.png - - \ No newline at end of file diff --git a/examples/animation/easing/form.ui b/examples/animation/easing/form.ui deleted file mode 100644 index b60ade8..0000000 --- a/examples/animation/easing/form.ui +++ /dev/null @@ -1,201 +0,0 @@ - - - Form - - - - 0 - 0 - 545 - 471 - - - - Easing curves - - - - - - - 0 - 0 - - - - - 16777215 - 120 - - - - Qt::ScrollBarAlwaysOff - - - QListView::Static - - - false - - - QListView::IconMode - - - false - - - - - - - - - Path type - - - - - - Line - - - true - - - buttonGroup - - - - - - - Circle - - - buttonGroup - - - - - - - - - - - 0 - 0 - - - - Properties - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Period - - - - - - - false - - - -1.000000000000000 - - - 0.100000000000000 - - - -1.000000000000000 - - - - - - - Amplitude - - - - - - - false - - - -1.000000000000000 - - - 0.100000000000000 - - - -1.000000000000000 - - - - - - - Overshoot - - - - - - - false - - - -1.000000000000000 - - - 0.100000000000000 - - - -1.000000000000000 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - - - - - - - diff --git a/examples/animation/easing/images/qt-logo.png b/examples/animation/easing/images/qt-logo.png deleted file mode 100644 index 14ddf2a..0000000 Binary files a/examples/animation/easing/images/qt-logo.png and /dev/null differ diff --git a/examples/animation/easing/main.cpp b/examples/animation/easing/main.cpp deleted file mode 100644 index bd10df2..0000000 --- a/examples/animation/easing/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "window.h" - -int main(int argc, char **argv) -{ - Q_INIT_RESOURCE(easing); - QApplication app(argc, argv); - Window w; - w.resize(400, 400); - w.show(); - return app.exec(); -} diff --git a/examples/animation/easing/window.cpp b/examples/animation/easing/window.cpp deleted file mode 100644 index cf4be15..0000000 --- a/examples/animation/easing/window.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "window.h" - -Window::Window(QWidget *parent) - : QWidget(parent), m_iconSize(64, 64) -{ - m_ui.setupUi(this); - QButtonGroup *buttonGroup = qFindChild(this); // ### workaround for uic in 4.4 - m_ui.easingCurvePicker->setIconSize(m_iconSize); - m_ui.easingCurvePicker->setMinimumHeight(m_iconSize.height() + 50); - buttonGroup->setId(m_ui.lineRadio, 0); - buttonGroup->setId(m_ui.circleRadio, 1); - - QEasingCurve dummy; - m_ui.periodSpinBox->setValue(dummy.period()); - m_ui.amplitudeSpinBox->setValue(dummy.amplitude()); - m_ui.overshootSpinBox->setValue(dummy.overshoot()); - - connect(m_ui.easingCurvePicker, SIGNAL(currentRowChanged(int)), this, SLOT(curveChanged(int))); - connect(buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(pathChanged(int))); - connect(m_ui.periodSpinBox, SIGNAL(valueChanged(double)), this, SLOT(periodChanged(double))); - connect(m_ui.amplitudeSpinBox, SIGNAL(valueChanged(double)), this, SLOT(amplitudeChanged(double))); - connect(m_ui.overshootSpinBox, SIGNAL(valueChanged(double)), this, SLOT(overshootChanged(double))); - createCurveIcons(); - - QPixmap pix(QLatin1String(":/images/qt-logo.png")); - m_item = new PixmapItem(pix); - m_scene.addItem(m_item); - m_ui.graphicsView->setScene(&m_scene); - - m_anim = new Animation(m_item, "pos"); - m_anim->setEasingCurve(QEasingCurve::OutBounce); - m_ui.easingCurvePicker->setCurrentRow(int(QEasingCurve::OutBounce)); - - startAnimation(); -} - -void Window::createCurveIcons() -{ - QPixmap pix(m_iconSize); - QPainter painter(&pix); - QLinearGradient gradient(0,0, 0, m_iconSize.height()); - gradient.setColorAt(0.0, QColor(240, 240, 240)); - gradient.setColorAt(1.0, QColor(224, 224, 224)); - QBrush brush(gradient); - const QMetaObject &mo = QEasingCurve::staticMetaObject; - QMetaEnum metaEnum = mo.enumerator(mo.indexOfEnumerator("Type")); - // Skip QEasingCurve::Custom - for (int i = 0; i < QEasingCurve::NCurveTypes - 1; ++i) { - painter.fillRect(QRect(QPoint(0, 0), m_iconSize), brush); - QEasingCurve curve((QEasingCurve::Type)i); - painter.setPen(QColor(0, 0, 255, 64)); - qreal xAxis = m_iconSize.height()/1.5; - qreal yAxis = m_iconSize.width()/3; - painter.drawLine(0, xAxis, m_iconSize.width(), xAxis); - painter.drawLine(yAxis, 0, yAxis, m_iconSize.height()); - painter.setPen(Qt::black); - - qreal curveScale = m_iconSize.height()/2; - QPoint currentPos(yAxis, xAxis); - - for (qreal t = 0; t < 1.0; t+=1.0/curveScale) { - QPoint to; - to.setX(yAxis + curveScale * t); - to.setY(xAxis - curveScale * curve.valueForProgress(t)); - painter.drawLine(currentPos, to); - currentPos = to; - } - QListWidgetItem *item = new QListWidgetItem; - item->setIcon(QIcon(pix)); - item->setText(metaEnum.key(i)); - m_ui.easingCurvePicker->addItem(item); - } -} - -void Window::startAnimation() -{ - m_anim->setStartValue(QPointF(0, 0)); - m_anim->setEndValue(QPointF(100, 100)); - m_anim->setDuration(2000); - m_anim->setLoopCount(-1); // forever - m_anim->start(); -} - -void Window::curveChanged(int row) -{ - QEasingCurve::Type curveType = (QEasingCurve::Type)row; - m_anim->setEasingCurve(curveType); - m_anim->setCurrentTime(0); - - bool isElastic = curveType >= QEasingCurve::InElastic && curveType <= QEasingCurve::OutInElastic; - bool isBounce = curveType >= QEasingCurve::InBounce && curveType <= QEasingCurve::OutInBounce; - m_ui.periodSpinBox->setEnabled(isElastic); - m_ui.amplitudeSpinBox->setEnabled(isElastic || isBounce); - m_ui.overshootSpinBox->setEnabled(curveType >= QEasingCurve::InBack && curveType <= QEasingCurve::OutInBack); -} - -void Window::pathChanged(int index) -{ - m_anim->setPathType((Animation::PathType)index); -} - -void Window::periodChanged(double value) -{ - QEasingCurve curve = m_anim->easingCurve(); - curve.setPeriod(value); - m_anim->setEasingCurve(curve); -} - -void Window::amplitudeChanged(double value) -{ - QEasingCurve curve = m_anim->easingCurve(); - curve.setAmplitude(value); - m_anim->setEasingCurve(curve); -} - -void Window::overshootChanged(double value) -{ - QEasingCurve curve = m_anim->easingCurve(); - curve.setOvershoot(value); - m_anim->setEasingCurve(curve); -} - diff --git a/examples/animation/easing/window.h b/examples/animation/easing/window.h deleted file mode 100644 index f3a8cb3..0000000 --- a/examples/animation/easing/window.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "ui_form.h" -#include "animation.h" - -class PixmapItem : public QObject, public QGraphicsPixmapItem -{ - Q_OBJECT - Q_PROPERTY(QPointF pos READ pos WRITE setPos) -public: - PixmapItem(const QPixmap &pix) : QGraphicsPixmapItem(pix) - { - } -}; - -class Window : public QWidget { - Q_OBJECT -public: - Window(QWidget *parent = 0); -private slots: - void curveChanged(int row); - void pathChanged(int index); - void periodChanged(double); - void amplitudeChanged(double); - void overshootChanged(double); - -private: - void createCurveIcons(); - void startAnimation(); - - Ui::Form m_ui; - QGraphicsScene m_scene; - PixmapItem *m_item; - Animation *m_anim; - QSize m_iconSize; - - -}; diff --git a/examples/animation/moveblocks/main.cpp b/examples/animation/moveblocks/main.cpp deleted file mode 100644 index b00485e..0000000 --- a/examples/animation/moveblocks/main.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include - -class StateSwitchEvent: public QEvent -{ -public: - StateSwitchEvent() - : QEvent(Type(StateSwitchType)) - { - } - - StateSwitchEvent(int rand) - : QEvent(Type(StateSwitchType)), - m_rand(rand) - { - } - - enum { StateSwitchType = QEvent::User + 256 }; - - int rand() const { return m_rand; } - -private: - int m_rand; -}; - - -class QGraphicsRectWidget : public QGraphicsWidget -{ -public: - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, - QWidget *) - { - painter->fillRect(rect(), Qt::blue); - } -}; - -class StateSwitchTransition: public QAbstractTransition -{ -public: - StateSwitchTransition(int rand) - : QAbstractTransition(), - m_rand(rand) - { - } - -protected: - virtual bool eventTest(QEvent *event) - { - return (event->type() == QEvent::Type(StateSwitchEvent::StateSwitchType)) - && (static_cast(event)->rand() == m_rand); - } - - virtual void onTransition(QEvent *) {} - -private: - int m_rand; -}; - -class StateSwitcher : public QState -{ - Q_OBJECT -public: - StateSwitcher(QStateMachine *machine) - : QState(machine->rootState()), m_machine(machine), - m_stateCount(0), m_lastIndex(0) - { } - - virtual void onEntry(QEvent *) - { - int n; - while ((n = (qrand() % m_stateCount + 1)) == m_lastIndex) - { } - m_lastIndex = n; - m_machine->postEvent(new StateSwitchEvent(n)); - } - virtual void onExit(QEvent *) {} - - void addState(QState *state, QAbstractAnimation *animation) { - StateSwitchTransition *trans = new StateSwitchTransition(++m_stateCount); - trans->setTargetState(state); - addTransition(trans); - trans->addAnimation(animation); - } - - -private: - QStateMachine *m_machine; - int m_stateCount; - int m_lastIndex; -}; - -QState *createGeometryState(QObject *w1, const QRect &rect1, - QObject *w2, const QRect &rect2, - QObject *w3, const QRect &rect3, - QObject *w4, const QRect &rect4, - QState *parent) -{ - QState *result = new QState(parent); - result->assignProperty(w1, "geometry", rect1); - result->assignProperty(w1, "geometry", rect1); - result->assignProperty(w2, "geometry", rect2); - result->assignProperty(w3, "geometry", rect3); - result->assignProperty(w4, "geometry", rect4); - - return result; -} - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - -#if 0 - QWidget window; - QPalette palette; - palette.setBrush(QPalette::Window, Qt::black); - window.setPalette(palette); - QPushButton *button1 = new QPushButton("A", &window); - QPushButton *button2 = new QPushButton("B", &window); - QPushButton *button3 = new QPushButton("C", &window); - QPushButton *button4 = new QPushButton("D", &window); - - button1->setObjectName("button1"); - button2->setObjectName("button2"); - button3->setObjectName("button3"); - button4->setObjectName("button4"); -#else - QGraphicsRectWidget *button1 = new QGraphicsRectWidget; - QGraphicsRectWidget *button2 = new QGraphicsRectWidget; - QGraphicsRectWidget *button3 = new QGraphicsRectWidget; - QGraphicsRectWidget *button4 = new QGraphicsRectWidget; - button2->setZValue(1); - button3->setZValue(2); - button4->setZValue(3); - QGraphicsScene scene(0, 0, 300, 300); - scene.setBackgroundBrush(Qt::black); - scene.addItem(button1); - scene.addItem(button2); - scene.addItem(button3); - scene.addItem(button4); - - QGraphicsView window(&scene); - window.setFrameStyle(0); - window.setAlignment(Qt::AlignLeft | Qt::AlignTop); - window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -#endif - QStateMachine machine; - - QState *group = new QState(); - group->setObjectName("group"); - QTimer timer; - timer.setInterval(1250); - timer.setSingleShot(true); - QObject::connect(group, SIGNAL(entered()), &timer, SLOT(start())); - - QState *state1; - QState *state2; - QState *state3; - QState *state4; - QState *state5; - QState *state6; - QState *state7; - - state1 = createGeometryState(button1, QRect(100, 0, 50, 50), - button2, QRect(150, 0, 50, 50), - button3, QRect(200, 0, 50, 50), - button4, QRect(250, 0, 50, 50), - group); - state2 = createGeometryState(button1, QRect(250, 100, 50, 50), - button2, QRect(250, 150, 50, 50), - button3, QRect(250, 200, 50, 50), - button4, QRect(250, 250, 50, 50), - group); - state3 = createGeometryState(button1, QRect(150, 250, 50, 50), - button2, QRect(100, 250, 50, 50), - button3, QRect(50, 250, 50, 50), - button4, QRect(0, 250, 50, 50), - group); - state4 = createGeometryState(button1, QRect(0, 150, 50, 50), - button2, QRect(0, 100, 50, 50), - button3, QRect(0, 50, 50, 50), - button4, QRect(0, 0, 50, 50), - group); - state5 = createGeometryState(button1, QRect(100, 100, 50, 50), - button2, QRect(150, 100, 50, 50), - button3, QRect(100, 150, 50, 50), - button4, QRect(150, 150, 50, 50), - group); - state6 = createGeometryState(button1, QRect(50, 50, 50, 50), - button2, QRect(200, 50, 50, 50), - button3, QRect(50, 200, 50, 50), - button4, QRect(200, 200, 50, 50), - group); - state7 = createGeometryState(button1, QRect(0, 0, 50, 50), - button2, QRect(250, 0, 50, 50), - button3, QRect(0, 250, 50, 50), - button4, QRect(250, 250, 50, 50), - group); - group->setInitialState(state1); - - QParallelAnimationGroup animationGroup; - QSequentialAnimationGroup *subGroup; - - QPropertyAnimation *anim = new QPropertyAnimation(button4, "geometry"); - anim->setDuration(1000); - anim->setEasingCurve(QEasingCurve::OutElastic); - animationGroup.addAnimation(anim); - - subGroup = new QSequentialAnimationGroup(&animationGroup); - subGroup->addPause(100); - anim = new QPropertyAnimation(button3, "geometry"); - anim->setDuration(1000); - anim->setEasingCurve(QEasingCurve::OutElastic); - subGroup->addAnimation(anim); - - subGroup = new QSequentialAnimationGroup(&animationGroup); - subGroup->addPause(150); - anim = new QPropertyAnimation(button2, "geometry"); - anim->setDuration(1000); - anim->setEasingCurve(QEasingCurve::OutElastic); - subGroup->addAnimation(anim); - - subGroup = new QSequentialAnimationGroup(&animationGroup); - subGroup->addPause(200); - anim = new QPropertyAnimation(button1, "geometry"); - anim->setDuration(1000); - anim->setEasingCurve(QEasingCurve::OutElastic); - subGroup->addAnimation(anim); - - StateSwitcher *stateSwitcher = new StateSwitcher(&machine); - stateSwitcher->setObjectName("stateSwitcher"); - group->addTransition(&timer, SIGNAL(timeout()), stateSwitcher); - stateSwitcher->addState(state1, &animationGroup); - stateSwitcher->addState(state2, &animationGroup); - stateSwitcher->addState(state3, &animationGroup); - stateSwitcher->addState(state4, &animationGroup); - stateSwitcher->addState(state5, &animationGroup); - stateSwitcher->addState(state6, &animationGroup); - stateSwitcher->addState(state7, &animationGroup); - - machine.addState(group); - machine.setInitialState(group); - machine.start(); - - - window.resize(300, 300); - window.show(); - - qsrand(time(0)); - - return app.exec(); -} - -#include "main.moc" diff --git a/examples/animation/moveblocks/moveblocks.pro b/examples/animation/moveblocks/moveblocks.pro deleted file mode 100644 index b8e88b2..0000000 --- a/examples/animation/moveblocks/moveblocks.pro +++ /dev/null @@ -1,7 +0,0 @@ -SOURCES = main.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/animation/moveblocks -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS moveblocks.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/animation/moveblocks -INSTALLS += target sources diff --git a/examples/animation/states/accessories-dictionary.png b/examples/animation/states/accessories-dictionary.png deleted file mode 100644 index e9bd55d..0000000 Binary files a/examples/animation/states/accessories-dictionary.png and /dev/null differ diff --git a/examples/animation/states/akregator.png b/examples/animation/states/akregator.png deleted file mode 100644 index a086f45..0000000 Binary files a/examples/animation/states/akregator.png and /dev/null differ diff --git a/examples/animation/states/digikam.png b/examples/animation/states/digikam.png deleted file mode 100644 index 9de9fb2..0000000 Binary files a/examples/animation/states/digikam.png and /dev/null differ diff --git a/examples/animation/states/help-browser.png b/examples/animation/states/help-browser.png deleted file mode 100644 index db92faa..0000000 Binary files a/examples/animation/states/help-browser.png and /dev/null differ diff --git a/examples/animation/states/k3b.png b/examples/animation/states/k3b.png deleted file mode 100644 index bbcafcf..0000000 Binary files a/examples/animation/states/k3b.png and /dev/null differ diff --git a/examples/animation/states/kchart.png b/examples/animation/states/kchart.png deleted file mode 100644 index 1dd115b..0000000 Binary files a/examples/animation/states/kchart.png and /dev/null differ diff --git a/examples/animation/states/main.cpp b/examples/animation/states/main.cpp deleted file mode 100644 index 17a7a8e..0000000 --- a/examples/animation/states/main.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -class Pixmap : public QGraphicsWidget -{ - Q_OBJECT -public: - Pixmap(const QPixmap &pix) : QGraphicsWidget(), p(pix) - { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) - { - painter->drawPixmap(QPointF(), p); - } - -protected: - QSizeF sizeHint(Qt::SizeHint, const QSizeF & = QSizeF()) - { - return QSizeF(p.width(), p.height()); - } - -private: - QPixmap p; -}; - -int main(int argc, char *argv[]) -{ - Q_INIT_RESOURCE(states); - - QApplication app(argc, argv); - - // Text edit and button - QTextEdit *edit = new QTextEdit; - edit->setText("asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " - "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " - "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " - "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy!"); - - QPushButton *button = new QPushButton; - QGraphicsProxyWidget *buttonProxy = new QGraphicsProxyWidget; - buttonProxy->setWidget(button); - QGraphicsProxyWidget *editProxy = new QGraphicsProxyWidget; - editProxy->setWidget(edit); - - QGroupBox *box = new QGroupBox; - box->setFlat(true); - box->setTitle("Options"); - - QVBoxLayout *layout2 = new QVBoxLayout; - box->setLayout(layout2); - layout2->addWidget(new QRadioButton("Herring")); - layout2->addWidget(new QRadioButton("Blue Parrot")); - layout2->addWidget(new QRadioButton("Petunias")); - layout2->addStretch(); - - QGraphicsProxyWidget *boxProxy = new QGraphicsProxyWidget; - boxProxy->setWidget(box); - - // Parent widget - QGraphicsWidget *widget = new QGraphicsWidget; - QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, widget); - layout->addItem(editProxy); - layout->addItem(buttonProxy); - widget->setLayout(layout); - - Pixmap *p1 = new Pixmap(QPixmap(":/digikam.png")); - Pixmap *p2 = new Pixmap(QPixmap(":/akregator.png")); - Pixmap *p3 = new Pixmap(QPixmap(":/accessories-dictionary.png")); - Pixmap *p4 = new Pixmap(QPixmap(":/k3b.png")); - Pixmap *p5 = new Pixmap(QPixmap(":/help-browser.png")); - Pixmap *p6 = new Pixmap(QPixmap(":/kchart.png")); - - QGraphicsScene scene(0, 0, 400, 300); - scene.setBackgroundBrush(scene.palette().window()); - scene.addItem(widget); - scene.addItem(boxProxy); - scene.addItem(p1); - scene.addItem(p2); - scene.addItem(p3); - scene.addItem(p4); - scene.addItem(p5); - scene.addItem(p6); - - QStateMachine machine; - QState *root = machine.rootState(); - QState *state1 = new QState(root); - QState *state2 = new QState(root); - QState *state3 = new QState(root); - machine.setInitialState(state1); - - // State 1 - state1->assignProperty(button, "text", "Switch to state 2"); - state1->assignProperty(widget, "geometry", QRectF(0, 0, 400, 150)); - state1->assignProperty(box, "geometry", QRect(-200, 150, 200, 150)); - state1->assignProperty(p1, "geometry", QRectF(68, 185, 64, 64)); - state1->assignProperty(p2, "geometry", QRectF(168, 185, 64, 64)); - state1->assignProperty(p3, "geometry", QRectF(268, 185, 64, 64)); - state1->assignProperty(p4, "geometry", QRectF(68-150, 48-150, 64, 64)); - state1->assignProperty(p5, "geometry", QRectF(168, 48-150, 64, 64)); - state1->assignProperty(p6, "geometry", QRectF(268+150, 48-150, 64, 64)); - state1->assignProperty(p1, "zRotation", qreal(0)); - state1->assignProperty(p2, "zRotation", qreal(0)); - state1->assignProperty(p3, "zRotation", qreal(0)); - state1->assignProperty(p4, "zRotation", qreal(-270)); - state1->assignProperty(p5, "zRotation", qreal(-90)); - state1->assignProperty(p6, "zRotation", qreal(270)); - state1->assignProperty(boxProxy, "opacity", qreal(0)); - state1->assignProperty(p1, "opacity", qreal(1)); - state1->assignProperty(p2, "opacity", qreal(1)); - state1->assignProperty(p3, "opacity", qreal(1)); - state1->assignProperty(p4, "opacity", qreal(0)); - state1->assignProperty(p5, "opacity", qreal(0)); - state1->assignProperty(p6, "opacity", qreal(0)); - - // State 2 - state2->assignProperty(button, "text", "Switch to state 3"); - state2->assignProperty(widget, "geometry", QRectF(200, 150, 200, 150)); - state2->assignProperty(box, "geometry", QRect(9, 150, 190, 150)); - state2->assignProperty(p1, "geometry", QRectF(68-150, 185+150, 64, 64)); - state2->assignProperty(p2, "geometry", QRectF(168, 185+150, 64, 64)); - state2->assignProperty(p3, "geometry", QRectF(268+150, 185+150, 64, 64)); - state2->assignProperty(p4, "geometry", QRectF(64, 48, 64, 64)); - state2->assignProperty(p5, "geometry", QRectF(168, 48, 64, 64)); - state2->assignProperty(p6, "geometry", QRectF(268, 48, 64, 64)); - state2->assignProperty(p1, "zRotation", qreal(-270)); - state2->assignProperty(p2, "zRotation", qreal(90)); - state2->assignProperty(p3, "zRotation", qreal(270)); - state2->assignProperty(p4, "zRotation", qreal(0)); - state2->assignProperty(p5, "zRotation", qreal(0)); - state2->assignProperty(p6, "zRotation", qreal(0)); - state2->assignProperty(boxProxy, "opacity", qreal(1)); - state2->assignProperty(p1, "opacity", qreal(0)); - state2->assignProperty(p2, "opacity", qreal(0)); - state2->assignProperty(p3, "opacity", qreal(0)); - state2->assignProperty(p4, "opacity", qreal(1)); - state2->assignProperty(p5, "opacity", qreal(1)); - state2->assignProperty(p6, "opacity", qreal(1)); - - // State 3 - state3->assignProperty(button, "text", "Switch to state 1"); - state3->assignProperty(p1, "geometry", QRectF(5, 5, 64, 64)); - state3->assignProperty(p2, "geometry", QRectF(5, 5 + 64 + 5, 64, 64)); - state3->assignProperty(p3, "geometry", QRectF(5, 5 + (64 + 5) + 64, 64, 64)); - state3->assignProperty(p4, "geometry", QRectF(5 + 64 + 5, 5, 64, 64)); - state3->assignProperty(p5, "geometry", QRectF(5 + 64 + 5, 5 + 64 + 5, 64, 64)); - state3->assignProperty(p6, "geometry", QRectF(5 + 64 + 5, 5 + (64 + 5) + 64, 64, 64)); - state3->assignProperty(widget, "geometry", QRectF(138, 5, 400 - 138, 200)); - state3->assignProperty(box, "geometry", QRect(5, 205, 400, 90)); - state3->assignProperty(p1, "opacity", qreal(1)); - state3->assignProperty(p2, "opacity", qreal(1)); - state3->assignProperty(p3, "opacity", qreal(1)); - state3->assignProperty(p4, "opacity", qreal(1)); - state3->assignProperty(p5, "opacity", qreal(1)); - state3->assignProperty(p6, "opacity", qreal(1)); - - QParallelAnimationGroup animation1; - - QSequentialAnimationGroup *animation1SubGroup; - animation1SubGroup = new QSequentialAnimationGroup(&animation1); - animation1SubGroup->addPause(250); - animation1SubGroup->addAnimation(new QPropertyAnimation(box, "geometry")); - - animation1.addAnimation(new QPropertyAnimation(widget, "geometry")); - animation1.addAnimation(new QPropertyAnimation(p1, "geometry")); - animation1.addAnimation(new QPropertyAnimation(p2, "geometry")); - animation1.addAnimation(new QPropertyAnimation(p3, "geometry")); - animation1.addAnimation(new QPropertyAnimation(p4, "geometry")); - animation1.addAnimation(new QPropertyAnimation(p5, "geometry")); - animation1.addAnimation(new QPropertyAnimation(p6, "geometry")); - animation1.addAnimation(new QPropertyAnimation(p1, "zRotation")); - animation1.addAnimation(new QPropertyAnimation(p2, "zRotation")); - animation1.addAnimation(new QPropertyAnimation(p3, "zRotation")); - animation1.addAnimation(new QPropertyAnimation(p4, "zRotation")); - animation1.addAnimation(new QPropertyAnimation(p5, "zRotation")); - animation1.addAnimation(new QPropertyAnimation(p6, "zRotation")); - animation1.addAnimation(new QPropertyAnimation(p1, "opacity")); - animation1.addAnimation(new QPropertyAnimation(p2, "opacity")); - animation1.addAnimation(new QPropertyAnimation(p3, "opacity")); - animation1.addAnimation(new QPropertyAnimation(p4, "opacity")); - animation1.addAnimation(new QPropertyAnimation(p5, "opacity")); - animation1.addAnimation(new QPropertyAnimation(p6, "opacity")); - - QParallelAnimationGroup animation2; - animation2.addAnimation(new QPropertyAnimation(box, "geometry")); - animation2.addAnimation(new QPropertyAnimation(widget, "geometry")); - animation2.addAnimation(new QPropertyAnimation(p1, "geometry")); - animation2.addAnimation(new QPropertyAnimation(p2, "geometry")); - animation2.addAnimation(new QPropertyAnimation(p3, "geometry")); - animation2.addAnimation(new QPropertyAnimation(p4, "geometry")); - animation2.addAnimation(new QPropertyAnimation(p5, "geometry")); - animation2.addAnimation(new QPropertyAnimation(p6, "geometry")); - animation2.addAnimation(new QPropertyAnimation(p1, "zRotation")); - animation2.addAnimation(new QPropertyAnimation(p2, "zRotation")); - animation2.addAnimation(new QPropertyAnimation(p3, "zRotation")); - animation2.addAnimation(new QPropertyAnimation(p4, "zRotation")); - animation2.addAnimation(new QPropertyAnimation(p5, "zRotation")); - animation2.addAnimation(new QPropertyAnimation(p6, "zRotation")); - animation2.addAnimation(new QPropertyAnimation(p1, "opacity")); - animation2.addAnimation(new QPropertyAnimation(p2, "opacity")); - animation2.addAnimation(new QPropertyAnimation(p3, "opacity")); - animation2.addAnimation(new QPropertyAnimation(p4, "opacity")); - animation2.addAnimation(new QPropertyAnimation(p5, "opacity")); - animation2.addAnimation(new QPropertyAnimation(p6, "opacity")); - - QParallelAnimationGroup animation3; - animation3.addAnimation(new QPropertyAnimation(box, "geometry")); - animation3.addAnimation(new QPropertyAnimation(widget, "geometry")); - animation3.addAnimation(new QPropertyAnimation(p1, "geometry")); - animation3.addAnimation(new QPropertyAnimation(p2, "geometry")); - animation3.addAnimation(new QPropertyAnimation(p3, "geometry")); - animation3.addAnimation(new QPropertyAnimation(p4, "geometry")); - animation3.addAnimation(new QPropertyAnimation(p5, "geometry")); - animation3.addAnimation(new QPropertyAnimation(p6, "geometry")); - animation3.addAnimation(new QPropertyAnimation(p1, "zRotation")); - animation3.addAnimation(new QPropertyAnimation(p2, "zRotation")); - animation3.addAnimation(new QPropertyAnimation(p3, "zRotation")); - animation3.addAnimation(new QPropertyAnimation(p4, "zRotation")); - animation3.addAnimation(new QPropertyAnimation(p5, "zRotation")); - animation3.addAnimation(new QPropertyAnimation(p6, "zRotation")); - animation3.addAnimation(new QPropertyAnimation(p1, "opacity")); - animation3.addAnimation(new QPropertyAnimation(p2, "opacity")); - animation3.addAnimation(new QPropertyAnimation(p3, "opacity")); - animation3.addAnimation(new QPropertyAnimation(p4, "opacity")); - animation3.addAnimation(new QPropertyAnimation(p5, "opacity")); - animation3.addAnimation(new QPropertyAnimation(p6, "opacity")); - - QAbstractTransition *t1 = state1->addTransition(button, SIGNAL(clicked()), state2); - t1->addAnimation(&animation1); - QAbstractTransition *t2 = state2->addTransition(button, SIGNAL(clicked()), state3); - t2->addAnimation(&animation2); - QAbstractTransition *t3 = state3->addTransition(button, SIGNAL(clicked()), state1); - t3->addAnimation(&animation3); - - machine.start(); - - QGraphicsView view(&scene); - view.show(); - - return app.exec(); -} - -#include "main.moc" diff --git a/examples/animation/states/states.pro b/examples/animation/states/states.pro deleted file mode 100644 index f4d1e0b..0000000 --- a/examples/animation/states/states.pro +++ /dev/null @@ -1,8 +0,0 @@ -SOURCES += main.cpp -RESOURCES += states.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/animation/states -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS states.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/animation/states -INSTALLS += target sources diff --git a/examples/animation/states/states.qrc b/examples/animation/states/states.qrc deleted file mode 100644 index 60ab3f7..0000000 --- a/examples/animation/states/states.qrc +++ /dev/null @@ -1,10 +0,0 @@ - - - accessories-dictionary.png - akregator.png - digikam.png - help-browser.png - k3b.png - kchart.png - - diff --git a/examples/animation/stickman/animation.cpp b/examples/animation/stickman/animation.cpp deleted file mode 100644 index c2c6bd1..0000000 --- a/examples/animation/stickman/animation.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "animation.h" - -#include -#include -#include - -class Frame -{ -public: - Frame() { - } - - int nodeCount() const - { - return m_nodePositions.size(); - } - - void setNodeCount(int nodeCount) - { - while (nodeCount > m_nodePositions.size()) - m_nodePositions.append(QPointF()); - - while (nodeCount < m_nodePositions.size()) - m_nodePositions.removeLast(); - } - - QPointF nodePos(int idx) const - { - return m_nodePositions.at(idx); - } - - void setNodePos(int idx, const QPointF &pos) - { - m_nodePositions[idx] = pos; - } - -private: - QList m_nodePositions; -}; - -Animation::Animation() -{ - m_currentFrame = 0; - m_frames.append(new Frame); -} - -Animation::~Animation() -{ - qDeleteAll(m_frames); -} - -void Animation::setTotalFrames(int totalFrames) -{ - while (m_frames.size() < totalFrames) - m_frames.append(new Frame); - - while (totalFrames < m_frames.size()) - delete m_frames.takeLast(); -} - -int Animation::totalFrames() const -{ - return m_frames.size(); -} - -void Animation::setCurrentFrame(int currentFrame) -{ - m_currentFrame = qMax(qMin(currentFrame, totalFrames()-1), 0); -} - -int Animation::currentFrame() const -{ - return m_currentFrame; -} - -void Animation::setNodeCount(int nodeCount) -{ - Frame *frame = m_frames.at(m_currentFrame); - frame->setNodeCount(nodeCount); -} - -int Animation::nodeCount() const -{ - Frame *frame = m_frames.at(m_currentFrame); - return frame->nodeCount(); -} - -void Animation::setNodePos(int idx, const QPointF &pos) -{ - Frame *frame = m_frames.at(m_currentFrame); - frame->setNodePos(idx, pos); -} - -QPointF Animation::nodePos(int idx) const -{ - Frame *frame = m_frames.at(m_currentFrame); - return frame->nodePos(idx); -} - -QString Animation::name() const -{ - return m_name; -} - -void Animation::setName(const QString &name) -{ - m_name = name; -} - -void Animation::save(QIODevice *device) const -{ - QDataStream stream(device); - stream << m_name; - stream << m_frames.size(); - foreach (Frame *frame, m_frames) { - stream << frame->nodeCount(); - for (int i=0; inodeCount(); ++i) - stream << frame->nodePos(i); - } -} - -void Animation::load(QIODevice *device) -{ - if (!m_frames.isEmpty()) - qDeleteAll(m_frames); - - m_frames.clear(); - - QDataStream stream(device); - stream >> m_name; - - int frameCount; - stream >> frameCount; - - for (int i=0; i> nodeCount; - - Frame *frame = new Frame; - frame->setNodeCount(nodeCount); - - for (int j=0; j> pos; - - frame->setNodePos(j, pos); - } - - m_frames.append(frame); - } -} diff --git a/examples/animation/stickman/animation.h b/examples/animation/stickman/animation.h deleted file mode 100644 index b0b39c9..0000000 --- a/examples/animation/stickman/animation.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANIMATION_H -#define ANIMATION_H - -#include -#include -#include - -class Frame; -QT_BEGIN_NAMESPACE -class QIODevice; -QT_END_NAMESPACE -class Animation -{ -public: - Animation(); - ~Animation(); - - void setTotalFrames(int totalFrames); - int totalFrames() const; - - void setCurrentFrame(int currentFrame); - int currentFrame() const; - - void setNodeCount(int nodeCount); - int nodeCount() const; - - void setNodePos(int idx, const QPointF &pos); - QPointF nodePos(int idx) const; - - QString name() const; - void setName(const QString &name); - - void save(QIODevice *device) const; - void load(QIODevice *device); - -private: - QString m_name; - QList m_frames; - int m_currentFrame; -}; - -#endif diff --git a/examples/animation/stickman/animations/chilling b/examples/animation/stickman/animations/chilling deleted file mode 100644 index a81fc7a..0000000 Binary files a/examples/animation/stickman/animations/chilling and /dev/null differ diff --git a/examples/animation/stickman/animations/dancing b/examples/animation/stickman/animations/dancing deleted file mode 100644 index 462f66f..0000000 Binary files a/examples/animation/stickman/animations/dancing and /dev/null differ diff --git a/examples/animation/stickman/animations/dead b/examples/animation/stickman/animations/dead deleted file mode 100644 index 9859b4b..0000000 Binary files a/examples/animation/stickman/animations/dead and /dev/null differ diff --git a/examples/animation/stickman/animations/jumping b/examples/animation/stickman/animations/jumping deleted file mode 100644 index 12661a1..0000000 Binary files a/examples/animation/stickman/animations/jumping and /dev/null differ diff --git a/examples/animation/stickman/editor/animationdialog.cpp b/examples/animation/stickman/editor/animationdialog.cpp deleted file mode 100644 index 441517d..0000000 --- a/examples/animation/stickman/editor/animationdialog.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "animationdialog.h" -#include "stickman.h" -#include "animation.h" -#include "node.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -AnimationDialog::AnimationDialog(StickMan *stickman, QWidget *parent) - : QDialog(parent), m_animation(0), m_stickman(stickman) -{ - initUi(); -} - -AnimationDialog::~AnimationDialog() -{ - delete m_animation; -} - -void AnimationDialog::initUi() -{ - setWindowTitle("Animation"); - setEnabled(false); - - // Second page - m_currentFrame = new QSpinBox(); - m_totalFrames = new QSpinBox(); - m_name = new QLineEdit(); - - connect(m_currentFrame, SIGNAL(valueChanged(int)), this, SLOT(currentFrameChanged(int))); - connect(m_totalFrames, SIGNAL(valueChanged(int)), this, SLOT(totalFramesChanged(int))); - connect(m_name, SIGNAL(textChanged(QString)), this, SLOT(setCurrentAnimationName(QString))); - - QGridLayout *gridLayout = new QGridLayout(this); - gridLayout->addWidget(new QLabel("Name:"), 0, 0, 1, 2); - gridLayout->addWidget(m_name, 0, 2, 1, 2); - gridLayout->addWidget(new QLabel("Frame:"), 1, 0); - gridLayout->addWidget(m_currentFrame, 1, 1); - gridLayout->addWidget(new QLabel("of total # of frames: "), 1, 2); - gridLayout->addWidget(m_totalFrames, 1, 3); -} - -void AnimationDialog::initFromAnimation() -{ - m_currentFrame->setRange(0, m_animation->totalFrames()-1); - m_currentFrame->setValue(m_animation->currentFrame()); - - m_totalFrames->setRange(1, 1000); - m_totalFrames->setValue(m_animation->totalFrames()); - - m_name->setText(m_animation->name()); -} - -void AnimationDialog::saveAnimation() -{ - saveCurrentFrame(); - - QString fileName = QFileDialog::getSaveFileName(this, "Save animation"); - - QFile file(fileName); - if (file.open(QIODevice::WriteOnly)) - m_animation->save(&file); -} - -void AnimationDialog::loadAnimation() -{ - if (maybeSave() != QMessageBox::Cancel) { - QString fileName = QFileDialog::getOpenFileName(this, "Open animation"); - - QFile file(fileName); - if (file.open(QIODevice::ReadOnly)) { - if (m_animation == 0) - newAnimation(); - - m_animation->load(&file); - stickManFromCurrentFrame(); - initFromAnimation(); - } - } -} - -QMessageBox::StandardButton AnimationDialog::maybeSave() -{ - if (m_animation == 0) - return QMessageBox::No; - - QMessageBox::StandardButton button = QMessageBox::question(this, "Save?", "Do you want to save your changes?", - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - if (button == QMessageBox::Save) - saveAnimation(); - - return button; -} - -void AnimationDialog::newAnimation() -{ - if (maybeSave() != QMessageBox::Cancel) { - setEnabled(true); - delete m_animation; - m_animation = new Animation(); - initFromAnimation(); - } -} - -// Gets the data from the stickman and stores it in current frame -void AnimationDialog::saveCurrentFrame() -{ - int count = m_stickman->nodeCount(); - m_animation->setNodeCount(count); - for (int i=0; inode(i); - m_animation->setNodePos(i, node->pos()); - } -} - -// Gets the data from the current frame and sets the stickman -void AnimationDialog::stickManFromCurrentFrame() -{ - int count = m_animation->nodeCount(); - for (int i=0;inode(i); - node->setPos(m_animation->nodePos(i)); - } -} - -void AnimationDialog::currentFrameChanged(int currentFrame) -{ - saveCurrentFrame(); - qDebug("currentFrame: %d", currentFrame); - m_animation->setCurrentFrame(currentFrame); - stickManFromCurrentFrame(); - initFromAnimation(); -} - -void AnimationDialog::totalFramesChanged(int totalFrames) -{ - m_animation->setTotalFrames(totalFrames); - stickManFromCurrentFrame(); - initFromAnimation(); -} - -void AnimationDialog::setCurrentAnimationName(const QString &name) -{ - m_animation->setName(name); -} diff --git a/examples/animation/stickman/editor/animationdialog.h b/examples/animation/stickman/editor/animationdialog.h deleted file mode 100644 index 6025088..0000000 --- a/examples/animation/stickman/editor/animationdialog.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANIMATIONDIALOG_H -#define ANIMATIONDIALOG_H - -#include -#include - -QT_BEGIN_NAMESPACE -class QSpinBox; -class QLineEdit; -QT_END_NAMESPACE -class StickMan; -class Animation; -class AnimationDialog: public QDialog -{ - Q_OBJECT -public: - AnimationDialog(StickMan *stickMan, QWidget *parent = 0); - ~AnimationDialog(); - -public slots: - void currentFrameChanged(int currentFrame); - void totalFramesChanged(int totalFrames); - void setCurrentAnimationName(const QString &name); - - void newAnimation(); - void saveAnimation(); - void loadAnimation(); - -private: - void saveCurrentFrame(); - void stickManFromCurrentFrame(); - void initFromAnimation(); - void initUi(); - QMessageBox::StandardButton maybeSave(); - - QSpinBox *m_currentFrame; - QSpinBox *m_totalFrames; - QLineEdit *m_name; - Animation *m_animation; - StickMan *m_stickman; -}; - -#endif diff --git a/examples/animation/stickman/editor/editor.pri b/examples/animation/stickman/editor/editor.pri deleted file mode 100644 index 7ad9edb..0000000 --- a/examples/animation/stickman/editor/editor.pri +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES += $$PWD/animationdialog.cpp $$PWD/mainwindow.cpp -HEADERS += $$PWD/animationdialog.h $$PWD/mainwindow.h diff --git a/examples/animation/stickman/editor/mainwindow.cpp b/examples/animation/stickman/editor/mainwindow.cpp deleted file mode 100644 index c6464c6..0000000 --- a/examples/animation/stickman/editor/mainwindow.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mainwindow.h" -#include "animationdialog.h" -#include "stickman.h" - -#include -#include - -MainWindow::MainWindow(StickMan *stickMan) -{ - initActions(stickMan); -} - -MainWindow::~MainWindow() -{ -} - -void MainWindow::initActions(StickMan *stickMan) -{ - AnimationDialog *dialog = new AnimationDialog(stickMan, this); - dialog->show(); - - QMenu *fileMenu = menuBar()->addMenu("&File"); - QAction *loadAction = fileMenu->addAction("&Open"); - QAction *saveAction = fileMenu->addAction("&Save"); - QAction *exitAction = fileMenu->addAction("E&xit"); - - QMenu *animationMenu = menuBar()->addMenu("&Animation"); - QAction *newAnimationAction = animationMenu->addAction("&New animation"); - - connect(loadAction, SIGNAL(triggered()), dialog, SLOT(loadAnimation())); - connect(saveAction, SIGNAL(triggered()), dialog, SLOT(saveAnimation())); - connect(exitAction, SIGNAL(triggered()), QApplication::instance(), SLOT(quit())); - connect(newAnimationAction, SIGNAL(triggered()), dialog, SLOT(newAnimation())); - -} diff --git a/examples/animation/stickman/editor/mainwindow.h b/examples/animation/stickman/editor/mainwindow.h deleted file mode 100644 index 4c2b949..0000000 --- a/examples/animation/stickman/editor/mainwindow.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include - -class StickMan; -class MainWindow: public QMainWindow -{ -public: - MainWindow(StickMan *stickMan); - ~MainWindow(); - -private: - void initActions(StickMan *stickMan); -}; - -#endif diff --git a/examples/animation/stickman/graphicsview.cpp b/examples/animation/stickman/graphicsview.cpp deleted file mode 100644 index 754f3bc..0000000 --- a/examples/animation/stickman/graphicsview.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graphicsview.h" -#include "editor/mainwindow.h" -#include "stickman.h" - -#include -#include -#include - -GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent), m_editor(0) {} - -void GraphicsView::keyPressEvent(QKeyEvent *e) -{ - if (e->key() == Qt::Key_Escape) - close(); - -#if 0 - if (e->key() == Qt::Key_F1) { - if (m_editor == 0) { - QGraphicsScene *scene = new QGraphicsScene; - StickMan *stickMan = new StickMan; - stickMan->setDrawSticks(true); - scene->addItem(stickMan); - - QGraphicsView *view = new QGraphicsView; - view->setBackgroundBrush(Qt::black); - view->setRenderHints(QPainter::Antialiasing); - view->setScene(scene); - - m_editor = new MainWindow(stickMan); - m_editor->setCentralWidget(view); - } - - m_editor->showMaximized(); - } -#endif - - emit keyPressed(Qt::Key(e->key())); -} - - diff --git a/examples/animation/stickman/graphicsview.h b/examples/animation/stickman/graphicsview.h deleted file mode 100644 index 2515418..0000000 --- a/examples/animation/stickman/graphicsview.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GRAPHICSVIEW_H -#define GRAPHICSVIEW - -#include - -class MainWindow; -class GraphicsView: public QGraphicsView -{ - Q_OBJECT -public: - GraphicsView(QWidget *parent = 0); - -protected: - void keyPressEvent(QKeyEvent *); - -signals: - void keyPressed(int key); - -private: - MainWindow *m_editor; -}; - -#endif diff --git a/examples/animation/stickman/lifecycle.cpp b/examples/animation/stickman/lifecycle.cpp deleted file mode 100644 index eb4ed11..0000000 --- a/examples/animation/stickman/lifecycle.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "lifecycle.h" -#include "stickman.h" -#include "node.h" -#include "animation.h" -#include "graphicsview.h" - -#include -#include - -class KeyPressTransition: public QSignalTransition -{ -public: - KeyPressTransition(GraphicsView *receiver, Qt::Key key) - : QSignalTransition(receiver, SIGNAL(keyPressed(int))), m_key(key) - { - } - KeyPressTransition(GraphicsView *receiver, Qt::Key key, QAbstractState *target) - : QSignalTransition(receiver, SIGNAL(keyPressed(int)), QList() << target), m_key(key) - { - } - - virtual bool eventTest(QEvent *e) - { - if (QSignalTransition::eventTest(e)) { - QVariant key = static_cast(e)->arguments().at(0); - return (key.toInt() == int(m_key)); - } - - return false; - } -private: - Qt::Key m_key; -}; - -//! [4] -class LightningStrikesTransition: public QEventTransition -{ -public: - LightningStrikesTransition(QAbstractState *target) - : QEventTransition(this, QEvent::Timer, QList() << target) - { - qsrand((uint)QDateTime::currentDateTime().toTime_t()); - startTimer(1000); - } - - virtual bool eventTest(QEvent *e) - { - return QEventTransition::eventTest(e) && ((qrand() % 50) == 0); - } -}; -//! [4] - -LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) - : m_stickMan(stickMan), m_keyReceiver(keyReceiver) -{ - // Create animation group to be used for all transitions - m_animationGroup = new QParallelAnimationGroup(); - const int stickManNodeCount = m_stickMan->nodeCount(); - for (int i=0; inode(i), "position"); - m_animationGroup->addAnimation(pa); - } - - // Set up intial state graph -//! [3] - m_machine = new QStateMachine(); - m_machine->addDefaultAnimation(m_animationGroup); -//! [3] - - m_alive = new QState(m_machine->rootState()); - m_alive->setObjectName("alive"); - - // Make it blink when lightning strikes before entering dead animation - QState *lightningBlink = new QState(m_machine->rootState()); - lightningBlink->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::white); - lightningBlink->assignProperty(m_stickMan, "penColor", Qt::black); - lightningBlink->assignProperty(m_stickMan, "fillColor", Qt::white); - lightningBlink->assignProperty(m_stickMan, "isDead", true); - -//! [5] - QTimer *timer = new QTimer(lightningBlink); - timer->setSingleShot(true); - timer->setInterval(100); - QObject::connect(lightningBlink, SIGNAL(entered()), timer, SLOT(start())); - QObject::connect(lightningBlink, SIGNAL(exited()), timer, SLOT(stop())); -//! [5] - - m_dead = new QState(m_machine->rootState()); - m_dead->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::black); - m_dead->assignProperty(m_stickMan, "penColor", Qt::white); - m_dead->assignProperty(m_stickMan, "fillColor", Qt::black); - m_dead->setObjectName("dead"); - - // Idle state (sets no properties) - m_idle = new QState(m_alive); - m_idle->setObjectName("idle"); - - m_alive->setInitialState(m_idle); - - // Lightning strikes at random - m_alive->addTransition(new LightningStrikesTransition(lightningBlink)); -//! [0] - lightningBlink->addTransition(timer, SIGNAL(timeout()), m_dead); -//! [0] - - m_machine->setInitialState(m_alive); -} - -void LifeCycle::setDeathAnimation(const QString &fileName) -{ - QState *deathAnimation = makeState(m_dead, fileName); - m_dead->setInitialState(deathAnimation); -} - -void LifeCycle::start() -{ - m_machine->start(); -} - -void LifeCycle::addActivity(const QString &fileName, Qt::Key key) -{ - QState *state = makeState(m_alive, fileName); - m_alive->addTransition(new KeyPressTransition(m_keyReceiver, key, state)); -} - -QState *LifeCycle::makeState(QState *parentState, const QString &animationFileName) -{ - QState *topLevel = new QState(parentState); - - Animation animation; - { - QFile file(animationFileName); - if (file.open(QIODevice::ReadOnly)) - animation.load(&file); - } - - const int frameCount = animation.totalFrames(); - QState *previousState = 0; - for (int i=0; iassignProperty(m_stickMan->node(j), "position", animation.nodePos(j)); -//! [1] - - frameState->setObjectName(QString::fromLatin1("frame %0").arg(i)); - if (previousState == 0) - topLevel->setInitialState(frameState); - else -//! [2] - previousState->addTransition(previousState, SIGNAL(polished()), frameState); -//! [2] - - previousState = frameState; - } - - // Loop - previousState->addTransition(previousState, SIGNAL(polished()), topLevel->initialState()); - - return topLevel; - -} - -LifeCycle::~LifeCycle() -{ - delete m_machine; - delete m_animationGroup; -} diff --git a/examples/animation/stickman/lifecycle.h b/examples/animation/stickman/lifecycle.h deleted file mode 100644 index 2be4762..0000000 --- a/examples/animation/stickman/lifecycle.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef LIFECYCLE_H -#define LIFECYCLE_H - -#include - -class StickMan; -QT_BEGIN_NAMESPACE -class QStateMachine; -class QAnimationGroup; -class QState; -class QAbstractState; -class QAbstractTransition; -QT_END_NAMESPACE -class GraphicsView; -class LifeCycle -{ -public: - LifeCycle(StickMan *stickMan, GraphicsView *keyEventReceiver); - ~LifeCycle(); - - void setDeathAnimation(const QString &fileName); - void addActivity(const QString &fileName, Qt::Key key); - - void start(); - -private: - QState *makeState(QState *parentState, const QString &animationFileName); - - StickMan *m_stickMan; - QStateMachine *m_machine; - QAnimationGroup *m_animationGroup; - GraphicsView *m_keyReceiver; - - QState *m_alive; - QState *m_dead; - QState *m_idle; -}; - -#endif diff --git a/examples/animation/stickman/main.cpp b/examples/animation/stickman/main.cpp deleted file mode 100644 index 62d8252..0000000 --- a/examples/animation/stickman/main.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "animation.h" -#include "node.h" -#include "lifecycle.h" -#include "stickman.h" -#include "graphicsview.h" - -#include -#include - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - StickMan *stickMan = new StickMan; - stickMan->setDrawSticks(false); - - QGraphicsTextItem *textItem = new QGraphicsTextItem(); - textItem->setHtml("Stickman" - "

    " - "Tell the stickman what to do!" - "

    " - "

    " - "

  • Press J to make the stickman jump.
  • " - "
  • Press D to make the stickman dance.
  • " - "
  • Press C to make him chill out.
  • " - "
  • When you are done, press Escape.
  • " - "

    " - "

    If he is unlucky, the stickman will get struck by lightning, and never jump, dance or chill out again." - "

    "); - qreal w = textItem->boundingRect().width(); - QRectF stickManBoundingRect = stickMan->mapToScene(stickMan->boundingRect()).boundingRect(); - textItem->setPos(-w / 2.0, stickManBoundingRect.bottom() + 25.0); - - QGraphicsScene *scene = new QGraphicsScene(); - scene->addItem(stickMan); - scene->addItem(textItem); - scene->setBackgroundBrush(Qt::black); - - GraphicsView *view = new GraphicsView(); - view->setRenderHints(QPainter::Antialiasing); - view->setTransformationAnchor(QGraphicsView::NoAnchor); - view->setScene(scene); - view->showFullScreen(); - view->setFocus(); - view->setSceneRect(scene->sceneRect()); - - LifeCycle *cycle = new LifeCycle(stickMan, view); - cycle->setDeathAnimation("animations/dead"); - - cycle->addActivity("animations/jumping", Qt::Key_J); - cycle->addActivity("animations/dancing", Qt::Key_D); - cycle->addActivity("animations/chilling", Qt::Key_C); - cycle->start(); - - return app.exec(); -} diff --git a/examples/animation/stickman/node.cpp b/examples/animation/stickman/node.cpp deleted file mode 100644 index 9c485d9..0000000 --- a/examples/animation/stickman/node.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "node.h" -#include "stickman.h" - -#include -#include -#include - -Node::Node(const QPointF &pos, QGraphicsItem *parent) - : QGraphicsItem(parent), m_dragging(false) -{ - setPos(pos); -} - -Node::~Node() -{ -} - -QRectF Node::boundingRect() const -{ - return QRectF(-6.0, -6.0, 12.0, 12.0); -} - -void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - painter->setPen(Qt::white); - painter->drawEllipse(QPointF(0.0, 0.0), 5.0, 5.0); -} - -QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) -{ - if (change == QGraphicsItem::ItemPositionChange) - emit positionChanged(); - - return QGraphicsItem::itemChange(change, value); -} - -void Node::mousePressEvent(QGraphicsSceneMouseEvent *) -{ - m_dragging = true; -} - -void Node::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - if (m_dragging) - setPos(mapToParent(event->pos())); -} - -void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *) -{ - m_dragging = false; -} diff --git a/examples/animation/stickman/node.h b/examples/animation/stickman/node.h deleted file mode 100644 index 72eae87..0000000 --- a/examples/animation/stickman/node.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef NODE_H -#define NODE_H - -#include - -class Node: public QObject, public QGraphicsItem -{ - Q_OBJECT - Q_PROPERTY(QPointF position READ pos WRITE setPos); -public: - Node(const QPointF &pos, QGraphicsItem *parent = 0); - ~Node(); - - QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - -signals: - void positionChanged(); - -protected: - QVariant itemChange(GraphicsItemChange change, const QVariant &value); - - void mousePressEvent(QGraphicsSceneMouseEvent *); - void mouseMoveEvent(QGraphicsSceneMouseEvent *); - void mouseReleaseEvent(QGraphicsSceneMouseEvent *); - -private: - bool m_dragging; -}; - -#endif diff --git a/examples/animation/stickman/stickman.cpp b/examples/animation/stickman/stickman.cpp deleted file mode 100644 index e00ea41..0000000 --- a/examples/animation/stickman/stickman.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "stickman.h" -#include "node.h" - -#include -#include - -#define _USE_MATH_DEFINES -#include - -static const int NodeCount = 16; -static const qreal Coords[NodeCount * 2] = { - 0.0, -150.0, // head, #0 - - 0.0, -100.0, // body pentagon, top->bottom, left->right, #1 - 5 - -50.0, -50.0, - 50.0, -50.0, - -25.0, 50.0, - 25.0, 50.0, - - -100.0, 0.0, // right arm, #6 - 7 - -125.0, 50.0, - - 100.0, 0.0, // left arm, #8 - 9 - 125.0, 50.0, - - -35.0, 75.0, // lower body, #10 - 11 - 35.0, 75.0, - - -25.0, 200.0, // right leg, #12 - 13 - -30.0, 300.0, - - 25.0, 200.0, // left leg, #14 - 15 - 30.0, 300.0 - -}; - -static const int BoneCount = 24; -static const int Bones[BoneCount * 2] = { - 0, 1, // neck - - 1, 2, // body - 1, 3, - 1, 4, - 1, 5, - 2, 3, - 2, 4, - 2, 5, - 3, 4, - 3, 5, - 4, 5, - - 2, 6, // right arm - 6, 7, - - 3, 8, // left arm - 8, 9, - - 4, 10, // lower body - 4, 11, - 5, 10, - 5, 11, - 10, 11, - - 10, 12, // right leg - 12, 13, - - 11, 14, // left leg - 14, 15 - -}; - -StickMan::StickMan() -{ - m_nodes = new Node*[NodeCount]; - m_sticks = true; - m_isDead = false; - m_pixmap = QPixmap("images/head.png"); - m_penColor = Qt::white; - m_fillColor = Qt::black; - - // Set up start position of limbs - for (int i=0; ipos() - node2->pos(); - m_perfectBoneLengths[i] = sqrt(pow(dist.x(),2) + pow(dist.y(),2)); - } - - startTimer(10); -} - -StickMan::~StickMan() -{ - delete m_nodes; -} - -void StickMan::childPositionChanged() -{ - prepareGeometryChange(); -} - -void StickMan::setDrawSticks(bool on) -{ - m_sticks = on; - for (int i=0;isetVisible(on); - } -} - -QRectF StickMan::boundingRect() const -{ - // account for head radius=50.0 plus pen which is 5.0 - return childrenBoundingRect().adjusted(-55.0, -55.0, 55.0, 55.0); -} - -int StickMan::nodeCount() const -{ - return NodeCount; -} - -Node *StickMan::node(int idx) const -{ - if (idx >= 0 && idx < NodeCount) - return m_nodes[idx]; - else - return 0; -} - -void StickMan::timerEvent(QTimerEvent *) -{ - update(); -} - -void StickMan::stabilize() -{ - static const qreal threshold = 0.001; - - for (int i=0; ipos(); - QPointF pos2 = node2->pos(); - - QPointF dist = pos1 - pos2; - qreal length = sqrt(pow(dist.x(),2) + pow(dist.y(),2)); - qreal diff = (length - m_perfectBoneLengths[i]) / length; - - QPointF p = dist * (0.5 * diff); - if (p.x() > threshold && p.y() > threshold) { - pos1 -= p; - pos2 += p; - - node1->setPos(pos1); - node2->setPos(pos2); - } - } -} - -QPointF StickMan::posFor(int idx) const -{ - return m_nodes[idx]->pos(); -} - -//#include -void StickMan::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - /* static int frames = 0; - static QTime time; - if (frames++ % 100 == 0) { - frames = 1; - time.restart(); - } - - if (time.elapsed() > 0) { - painter->setPen(Qt::white); - painter->drawText(0, 0, QString::number(frames / (time.elapsed() / 1000.0))); - }*/ - - stabilize(); - if (m_sticks) { - painter->setPen(Qt::white); - for (int i=0; idrawLine(node1->pos(), node2->pos()); - } - } else { - // first bone is neck and will be used for head - - QPainterPath path; - path.moveTo(posFor(0)); - path.lineTo(posFor(1)); - - // right arm - path.lineTo(posFor(2)); - path.lineTo(posFor(6)); - path.lineTo(posFor(7)); - - // left arm - path.moveTo(posFor(3)); - path.lineTo(posFor(8)); - path.lineTo(posFor(9)); - - // body - path.moveTo(posFor(2)); - path.lineTo(posFor(4)); - path.lineTo(posFor(10)); - path.lineTo(posFor(11)); - path.lineTo(posFor(5)); - path.lineTo(posFor(3)); - path.lineTo(posFor(1)); - - // right leg - path.moveTo(posFor(10)); - path.lineTo(posFor(12)); - path.lineTo(posFor(13)); - - // left leg - path.moveTo(posFor(11)); - path.lineTo(posFor(14)); - path.lineTo(posFor(15)); - - painter->setPen(QPen(m_penColor, 5.0, Qt::SolidLine, Qt::RoundCap)); - painter->drawPath(path); - - { - int n1 = Bones[0]; - int n2 = Bones[1]; - Node *node1 = m_nodes[n1]; - Node *node2 = m_nodes[n2]; - - QPointF dist = node2->pos() - node1->pos(); - - qreal sinAngle = dist.x() / sqrt(pow(dist.x(), 2) + pow(dist.y(), 2)); - qreal angle = asin(sinAngle) * 180.0 / M_PI; - - QPointF headPos = node1->pos(); - painter->translate(headPos); - painter->rotate(-angle); - - painter->setBrush(m_fillColor); - painter->drawEllipse(QPointF(0,0), 50.0, 50.0); - - painter->setBrush(m_penColor); - painter->setPen(QPen(m_penColor, 2.5, Qt::SolidLine, Qt::RoundCap)); - - // eyes - if (m_isDead) { - painter->drawLine(-30.0, -30.0, -20.0, -20.0); - painter->drawLine(-20.0, -30.0, -30.0, -20.0); - - painter->drawLine(20.0, -30.0, 30.0, -20.0); - painter->drawLine(30.0, -30.0, 20.0, -20.0); - } else { - painter->drawChord(QRectF(-30.0, -30.0, 25.0, 70.0), 30.0*16, 120.0*16); - painter->drawChord(QRectF(5.0, -30.0, 25.0, 70.0), 30.0*16, 120.0*16); - } - - // mouth - if (m_isDead) { - painter->drawLine(-28.0, 2.0, 29.0, 2.0); - } else { - painter->setBrush(QColor(128, 0, 64 )); - painter->drawChord(QRectF(-28.0, 2.0-55.0/2.0, 57.0, 55.0), 0.0, -180.0*16); - } - - // pupils - if (!m_isDead) { - painter->setPen(QPen(m_fillColor, 1.0, Qt::SolidLine, Qt::RoundCap)); - painter->setBrush(m_fillColor); - painter->drawEllipse(QPointF(-12.0, -25.0), 5.0, 5.0); - painter->drawEllipse(QPointF(22.0, -25.0), 5.0, 5.0); - } - } - } -} - - - diff --git a/examples/animation/stickman/stickman.h b/examples/animation/stickman/stickman.h deleted file mode 100644 index 6395272..0000000 --- a/examples/animation/stickman/stickman.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef STICKMAN_H -#define STICKMAN_H - -#include - -const int LimbCount = 16; - -class Node; -QT_BEGIN_NAMESPACE -class QTimer; -QT_END_NAMESPACE -class StickMan: public QObject, public QGraphicsItem -{ - Q_OBJECT - Q_PROPERTY(QColor penColor WRITE setPenColor READ penColor) - Q_PROPERTY(QColor fillColor WRITE setFillColor READ fillColor) - Q_PROPERTY(bool isDead WRITE setIsDead READ isDead) -public: - StickMan(); - ~StickMan(); - - virtual QRectF boundingRect() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - - int nodeCount() const; - Node *node(int idx) const; - - void setDrawSticks(bool on); - bool drawSticks() const { return m_sticks; } - - QColor penColor() const { return m_penColor; } - void setPenColor(const QColor &color) { m_penColor = color; } - - QColor fillColor() const { return m_fillColor; } - void setFillColor(const QColor &color) { m_fillColor = color; } - - bool isDead() const { return m_isDead; } - void setIsDead(bool isDead) { m_isDead = isDead; } - -public slots: - void stabilize(); - void childPositionChanged(); - -protected: - void timerEvent(QTimerEvent *e); - -private: - QPointF posFor(int idx) const; - - Node **m_nodes; - qreal *m_perfectBoneLengths; - - uint m_sticks : 1; - uint m_isDead : 1; - uint m_reserved : 30; - - QPixmap m_pixmap; - QColor m_penColor; - QColor m_fillColor; -}; - -#endif // STICKMAN_H diff --git a/examples/animation/stickman/stickman.pro b/examples/animation/stickman/stickman.pro deleted file mode 100644 index 956b49c..0000000 --- a/examples/animation/stickman/stickman.pro +++ /dev/null @@ -1,19 +0,0 @@ -HEADERS += stickman.h \ - animation.h \ - node.h \ - lifecycle.h \ - graphicsview.h -SOURCES += main.cpp \ - stickman.cpp \ - animation.cpp \ - node.cpp \ - lifecycle.cpp \ - graphicsview.cpp - -include(editor/editor.pri) - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/animation/stickman -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS stickman.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/animation/stickman -INSTALLS += target sources diff --git a/examples/animation/sub-attaq/animationmanager.cpp b/examples/animation/sub-attaq/animationmanager.cpp deleted file mode 100644 index 477d3bd..0000000 --- a/examples/animation/sub-attaq/animationmanager.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//Own -#include "animationmanager.h" - -//Qt -#include -#include - -// the universe's only animation manager -AnimationManager *AnimationManager::instance = 0; - -AnimationManager::AnimationManager() -{ -} - -AnimationManager *AnimationManager::self() -{ - if (!instance) - instance = new AnimationManager; - return instance; -} - -void AnimationManager::registerAnimation(QAbstractAnimation *anim) -{ - animations.append(anim); -} - -void AnimationManager::unregisterAnimation(QAbstractAnimation *anim) -{ - animations.removeAll(anim); -} - -void AnimationManager::unregisterAllAnimations() -{ - animations.clear(); -} - -void AnimationManager::pauseAll() -{ - foreach (QAbstractAnimation* animation, animations) - { - if (animation->state() == QAbstractAnimation::Running) - animation->pause(); - } -} -void AnimationManager::resumeAll() -{ - foreach (QAbstractAnimation* animation, animations) - { - if (animation->state() == QAbstractAnimation::Paused) - animation->resume(); - } -} diff --git a/examples/animation/sub-attaq/animationmanager.h b/examples/animation/sub-attaq/animationmanager.h deleted file mode 100644 index a563c96..0000000 --- a/examples/animation/sub-attaq/animationmanager.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANIMATIONMANAGER_H -#define ANIMATIONMANAGER_H - -#include - -QT_BEGIN_NAMESPACE -class QAbstractAnimation; -QT_END_NAMESPACE - -class AnimationManager : public QObject -{ -Q_OBJECT -public: - AnimationManager(); - void registerAnimation(QAbstractAnimation *anim); - void unregisterAnimation(QAbstractAnimation *anim); - void unregisterAllAnimations(); - static AnimationManager *self(); - -public slots: - void pauseAll(); - void resumeAll(); - -private: - static AnimationManager *instance; - QList animations; -}; - -#endif // ANIMATIONMANAGER_H diff --git a/examples/animation/sub-attaq/boat.cpp b/examples/animation/sub-attaq/boat.cpp deleted file mode 100644 index 63d12bb..0000000 --- a/examples/animation/sub-attaq/boat.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//Own -#include "boat.h" -#include "boat_p.h" -#include "bomb.h" -#include "pixmapitem.h" -#include "graphicsscene.h" -#include "animationmanager.h" -#include "custompropertyanimation.h" -#include "qanimationstate.h" - -//Qt -#include -#include -#include -#include -#include -#include - -static QAbstractAnimation *setupDestroyAnimation(Boat *boat) -{ - QSequentialAnimationGroup *group = new QSequentialAnimationGroup(boat); -#if QT_VERSION >=0x040500 - PixmapItem *step1 = new PixmapItem(QString("explosion/boat/step1"),GraphicsScene::Big, boat); - step1->setZValue(6); - PixmapItem *step2 = new PixmapItem(QString("explosion/boat/step2"),GraphicsScene::Big, boat); - step2->setZValue(6); - PixmapItem *step3 = new PixmapItem(QString("explosion/boat/step3"),GraphicsScene::Big, boat); - step3->setZValue(6); - PixmapItem *step4 = new PixmapItem(QString("explosion/boat/step4"),GraphicsScene::Big, boat); - step4->setZValue(6); - step1->setOpacity(0); - step2->setOpacity(0); - step3->setOpacity(0); - step4->setOpacity(0); - CustomPropertyAnimation *anim1 = new CustomPropertyAnimation(boat); - anim1->setMemberFunctions((QGraphicsItem*)step1, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim1->setDuration(100); - anim1->setEndValue(1); - CustomPropertyAnimation *anim2 = new CustomPropertyAnimation(boat); - anim2->setMemberFunctions((QGraphicsItem*)step2, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim2->setDuration(100); - anim2->setEndValue(1); - CustomPropertyAnimation *anim3 = new CustomPropertyAnimation(boat); - anim3->setMemberFunctions((QGraphicsItem*)step3, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim3->setDuration(100); - anim3->setEndValue(1); - CustomPropertyAnimation *anim4 = new CustomPropertyAnimation(boat); - anim4->setMemberFunctions((QGraphicsItem*)step4, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim4->setDuration(100); - anim4->setEndValue(1); - CustomPropertyAnimation *anim5 = new CustomPropertyAnimation(boat); - anim5->setMemberFunctions((QGraphicsItem*)step1, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim5->setDuration(100); - anim5->setEndValue(0); - CustomPropertyAnimation *anim6 = new CustomPropertyAnimation(boat); - anim6->setMemberFunctions((QGraphicsItem*)step2, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim6->setDuration(100); - anim6->setEndValue(0); - CustomPropertyAnimation *anim7 = new CustomPropertyAnimation(boat); - anim7->setMemberFunctions((QGraphicsItem*)step3, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim7->setDuration(100); - anim7->setEndValue(0); - CustomPropertyAnimation *anim8 = new CustomPropertyAnimation(boat); - anim8->setMemberFunctions((QGraphicsItem*)step4, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim8->setDuration(100); - anim8->setEndValue(0); - group->addAnimation(anim1); - group->addAnimation(anim2); - group->addAnimation(anim3); - group->addAnimation(anim4); - group->addAnimation(anim5); - group->addAnimation(anim6); - group->addAnimation(anim7); - group->addAnimation(anim8); -#else - // work around for a bug where we don't transition if the duration is zero. - QtPauseAnimation *anim = new QtPauseAnimation(group); - anim->setDuration(1); - group->addAnimation(anim); -#endif - AnimationManager::self()->registerAnimation(group); - return group; -} - - - -Boat::Boat(QGraphicsItem * parent, Qt::WindowFlags wFlags) - : QGraphicsWidget(parent,wFlags), speed(0), bombsAlreadyLaunched(0), direction(Boat::None), movementAnimation(0) -{ - pixmapItem = new PixmapItem(QString("boat"),GraphicsScene::Big, this); - setZValue(4); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable); - resize(pixmapItem->boundingRect().size()); - - //The movement animation used to animate the boat - movementAnimation = new QPropertyAnimation(this, "pos"); - - //The movement animation used to animate the boat - destroyAnimation = setupDestroyAnimation(this); - - //We setup the state machien of the boat - machine = new QStateMachine(this); - QState *moving = new QState(machine->rootState()); - StopState *stopState = new StopState(this, moving); - machine->setInitialState(moving); - moving->setInitialState(stopState); - MoveStateRight *moveStateRight = new MoveStateRight(this, moving); - MoveStateLeft *moveStateLeft = new MoveStateLeft(this, moving); - LaunchStateRight *launchStateRight = new LaunchStateRight(this, machine->rootState()); - LaunchStateLeft *launchStateLeft = new LaunchStateLeft(this, machine->rootState()); - - //then setup the transitions for the rightMove state - KeyStopTransition *leftStopRight = new KeyStopTransition(this, QEvent::KeyPress, Qt::Key_Left); - leftStopRight->setTargetState(stopState); - KeyMoveTransition *leftMoveRight = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Left); - leftMoveRight->setTargetState(moveStateRight); - KeyMoveTransition *rightMoveRight = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right); - rightMoveRight->setTargetState(moveStateRight); - KeyMoveTransition *rightMoveStop = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right); - rightMoveStop->setTargetState(moveStateRight); - - //then setup the transitions for the leftMove state - KeyStopTransition *rightStopLeft = new KeyStopTransition(this, QEvent::KeyPress, Qt::Key_Right); - rightStopLeft->setTargetState(stopState); - KeyMoveTransition *rightMoveLeft = new KeyMoveTransition(this, QEvent::KeyPress, Qt::Key_Right); - rightMoveLeft->setTargetState(moveStateLeft); - KeyMoveTransition *leftMoveLeft = new KeyMoveTransition(this, QEvent::KeyPress,Qt::Key_Left); - leftMoveLeft->setTargetState(moveStateLeft); - KeyMoveTransition *leftMoveStop = new KeyMoveTransition(this, QEvent::KeyPress,Qt::Key_Left); - leftMoveStop->setTargetState(moveStateLeft); - - //We set up the right move state - moveStateRight->addTransition(leftStopRight); - moveStateRight->addTransition(leftMoveRight); - moveStateRight->addTransition(rightMoveRight); - stopState->addTransition(rightMoveStop); - - //We set up the left move state - moveStateLeft->addTransition(rightStopLeft); - moveStateLeft->addTransition(leftMoveLeft); - moveStateLeft->addTransition(rightMoveLeft); - stopState->addTransition(leftMoveStop); - - //The animation is finished, it means we reached the border of the screen, the boat is stopped so we move to the stop state - moveStateLeft->addTransition(movementAnimation, SIGNAL(finished()), stopState); - moveStateRight->addTransition(movementAnimation, SIGNAL(finished()), stopState); - - //We set up the keys for dropping bombs - KeyLaunchTransition *upFireLeft = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up); - upFireLeft->setTargetState(launchStateRight); - KeyLaunchTransition *upFireRight = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up); - upFireRight->setTargetState(launchStateRight); - KeyLaunchTransition *upFireStop = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up); - upFireStop->setTargetState(launchStateRight); - KeyLaunchTransition *downFireLeft = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down); - downFireLeft->setTargetState(launchStateLeft); - KeyLaunchTransition *downFireRight = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down); - downFireRight->setTargetState(launchStateLeft); - KeyLaunchTransition *downFireMove = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Down); - downFireMove->setTargetState(launchStateLeft); - - //We set up transitions for fire up - moveStateRight->addTransition(upFireRight); - moveStateLeft->addTransition(upFireLeft); - stopState->addTransition(upFireStop); - - //We set up transitions for fire down - moveStateRight->addTransition(downFireRight); - moveStateLeft->addTransition(downFireLeft); - stopState->addTransition(downFireMove); - - //Finally the launch state should come back to its original state - QHistoryState *historyState = new QHistoryState(moving); - launchStateLeft->addTransition(historyState); - launchStateRight->addTransition(historyState); - - QFinalState *final = new QFinalState(machine->rootState()); - - //This state play the destroyed animation - QAnimationState *destroyedState = new QAnimationState(machine->rootState()); - destroyedState->setAnimation(destroyAnimation); - - //Play a nice animation when the boat is destroyed - moving->addTransition(this, SIGNAL(boatDestroyed()),destroyedState); - - //Transition to final state when the destroyed animation is finished - destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final); - - //The machine has finished to be executed, then the boat is dead - connect(machine,SIGNAL(finished()),this, SIGNAL(boatExecutionFinished())); - -} - -void Boat::run() -{ - //We register animations - AnimationManager::self()->registerAnimation(movementAnimation); - AnimationManager::self()->registerAnimation(destroyAnimation); - machine->start(); -} - -void Boat::stop() -{ - movementAnimation->stop(); - machine->stop(); -} - -void Boat::updateBoatMovement() -{ - if (speed == 0 || direction == Boat::None) { - movementAnimation->stop(); - return; - } - - movementAnimation->stop(); - movementAnimation->setStartValue(pos()); - - if (direction == Boat::Left) { - movementAnimation->setEndValue(QPointF(0,y())); - movementAnimation->setDuration(x()/speed*15); - } - else /*if (direction == Boat::Right)*/ { - movementAnimation->setEndValue(QPointF(scene()->width()-size().width(),y())); - movementAnimation->setDuration((scene()->width()-size().width()-x())/speed*15); - } - movementAnimation->start(); -} - -void Boat::destroy() -{ - movementAnimation->stop(); - emit boatDestroyed(); -} - -int Boat::bombsLaunched() const -{ - return bombsAlreadyLaunched; -} - -void Boat::setBombsLaunched(int number) -{ - if (number > MAX_BOMB) { - qWarning("Boat::setBombsLaunched : It impossible to launch that number of bombs"); - return; - } - bombsAlreadyLaunched = number; -} - -int Boat::currentSpeed() const -{ - return speed; -} - -void Boat::setCurrentSpeed(int speed) -{ - if (speed > 3 || speed < 0) { - qWarning("Boat::setCurrentSpeed: The boat can't run on that speed"); - return; - } - this->speed = speed; -} - -enum Boat::Movement Boat::currentDirection() const -{ - return direction; -} - -void Boat::setCurrentDirection(Movement direction) -{ - this->direction = direction; -} - -int Boat::type() const -{ - return Type; -} diff --git a/examples/animation/sub-attaq/boat.h b/examples/animation/sub-attaq/boat.h deleted file mode 100644 index 08a9fa2..0000000 --- a/examples/animation/sub-attaq/boat.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __BOAT__H__ -#define __BOAT__H__ - -//Qt -#include -#include - -#include - -class PixmapItem; -class Bomb; -QT_BEGIN_NAMESPACE -class QVariantAnimation; -class QAbstractAnimation; -class QStateMachine; -QT_END_NAMESPACE - -class Boat : public QGraphicsWidget -{ -Q_OBJECT -Q_PROPERTY(QPointF pos READ pos WRITE setPos) -public: - enum Movement { - None = 0, - Left, - Right - }; - enum { Type = UserType + 2 }; - Boat(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0); - void destroy(); - void run(); - void stop(); - - int bombsLaunched() const; - void setBombsLaunched(int number); - - int currentSpeed() const; - void setCurrentSpeed(int speed); - - enum Movement currentDirection() const; - void setCurrentDirection(Movement direction); - - void updateBoatMovement(); - - virtual int type() const; - -Q_SIGNALS: - void boatDestroyed(); - void boatExecutionFinished(); - -private: - int speed; - int bombsAlreadyLaunched; - Movement direction; - QVariantAnimation *movementAnimation; - QAbstractAnimation *destroyAnimation; - QStateMachine *machine; - PixmapItem *pixmapItem; -}; - -#endif //__BOAT__H__ diff --git a/examples/animation/sub-attaq/boat_p.h b/examples/animation/sub-attaq/boat_p.h deleted file mode 100644 index a8a24a6..0000000 --- a/examples/animation/sub-attaq/boat_p.h +++ /dev/null @@ -1,256 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BOAT_P_H -#define BOAT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -//Own -#include "bomb.h" -#include "graphicsscene.h" - -// Qt -#include - -static const int MAX_BOMB = 5; - - -//These transtion test if we have to stop the boat (i.e current speed is 1) -class KeyStopTransition : public QKeyEventTransition -{ -public: - KeyStopTransition(Boat *boat, QEvent::Type type, int key) - : QKeyEventTransition(boat, type, key) - { - this->boat = boat; - this->key = key; - } -protected: - virtual bool eventTest(QEvent *event) - { - Q_UNUSED(event); - if (!QKeyEventTransition::eventTest(event)) - return false; - if (boat->currentSpeed() == 1) - return true; - else - return false; - } -private: - Boat * boat; - int key; -}; - -//These transtion test if we have to move the boat (i.e current speed was 0 or another value) - class KeyMoveTransition : public QKeyEventTransition -{ -public: - KeyMoveTransition(Boat *boat, QEvent::Type type, int key) - : QKeyEventTransition(boat, type, key) - { - this->boat = boat; - this->key = key; - } -protected: - virtual bool eventTest(QEvent *event) - { - Q_UNUSED(event); - if (!QKeyEventTransition::eventTest(event)) - return false; - if (boat->currentSpeed() >= 0) - return true; - else - return false; - - } - void onTransition(QEvent *) - { - //We decrease the speed if needed - if (key == Qt::Key_Left && boat->currentDirection() == Boat::Right) - boat->setCurrentSpeed(boat->currentSpeed() - 1); - else if (key == Qt::Key_Right && boat->currentDirection() == Boat::Left) - boat->setCurrentSpeed(boat->currentSpeed() - 1); - else if (boat->currentSpeed() < 3) - boat->setCurrentSpeed(boat->currentSpeed() + 1); - boat->updateBoatMovement(); - } -private: - Boat * boat; - int key; -}; - -//This transition trigger the bombs launch - class KeyLaunchTransition : public QKeyEventTransition -{ -public: - KeyLaunchTransition(Boat *boat, QEvent::Type type, int key) - : QKeyEventTransition(boat, type, key) - { - this->boat = boat; - this->key = key; - } -protected: - virtual bool eventTest(QEvent *event) - { - Q_UNUSED(event); - if (!QKeyEventTransition::eventTest(event)) - return false; - //We have enough bomb? - if (boat->bombsLaunched() < MAX_BOMB) - return true; - else - return false; - } -private: - Boat * boat; - int key; -}; - -//This state is describing when the boat is moving right -class MoveStateRight : public QState -{ -public: - MoveStateRight(Boat *boat,QState *parent = 0) : QState(parent) - { - this->boat = boat; - } -protected: - void onEntry(QEvent *) - { - boat->setCurrentDirection(Boat::Right); - boat->updateBoatMovement(); - } -private: - Boat * boat; -}; - - //This state is describing when the boat is moving left -class MoveStateLeft : public QState -{ -public: - MoveStateLeft(Boat *boat,QState *parent = 0) : QState(parent) - { - this->boat = boat; - } -protected: - void onEntry(QEvent *) - { - boat->setCurrentDirection(Boat::Left); - boat->updateBoatMovement(); - } -private: - Boat * boat; -}; - -//This state is describing when the boat is in a stand by position -class StopState : public QState -{ -public: - StopState(Boat *boat,QState *parent = 0) : QState(parent) - { - this->boat = boat; - } -protected: - void onEntry(QEvent *) - { - boat->setCurrentSpeed(0); - boat->setCurrentDirection(Boat::None); - boat->updateBoatMovement(); - } -private: - Boat * boat; -}; - -//This state is describing the launch of the torpedo on the right -class LaunchStateRight : public QState -{ -public: - LaunchStateRight(Boat *boat,QState *parent = 0) : QState(parent) - { - this->boat = boat; - } -protected: - void onEntry(QEvent *) - { - Bomb *b = new Bomb(); - b->setPos(boat->x()+boat->size().width(),boat->y()); - GraphicsScene *scene = static_cast(boat->scene()); - scene->addItem(b); - b->launch(Bomb::Right); - boat->setBombsLaunched(boat->bombsLaunched() + 1); - } -private: - Boat * boat; -}; - -//This state is describing the launch of the torpedo on the left -class LaunchStateLeft : public QState -{ -public: - LaunchStateLeft(Boat *boat,QState *parent = 0) : QState(parent) - { - this->boat = boat; - } -protected: - void onEntry(QEvent *) - { - Bomb *b = new Bomb(); - b->setPos(boat->x() - b->size().width(), boat->y()); - GraphicsScene *scene = static_cast(boat->scene()); - scene->addItem(b); - b->launch(Bomb::Left); - boat->setBombsLaunched(boat->bombsLaunched() + 1); - } -private: - Boat * boat; -}; - -#endif // BOAT_P_H diff --git a/examples/animation/sub-attaq/bomb.cpp b/examples/animation/sub-attaq/bomb.cpp deleted file mode 100644 index f1f5324..0000000 --- a/examples/animation/sub-attaq/bomb.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//Own -#include "bomb.h" -#include "submarine.h" -#include "pixmapitem.h" -#include "animationmanager.h" -#include "qanimationstate.h" - -//Qt -#include -#include -#include -#include - -Bomb::Bomb(QGraphicsItem * parent, Qt::WindowFlags wFlags) - : QGraphicsWidget(parent,wFlags), launchAnimation(0) -{ - pixmapItem = new PixmapItem(QString("bomb"),GraphicsScene::Big, this); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setFlags(QGraphicsItem::ItemIsMovable); - setZValue(2); - resize(pixmapItem->boundingRect().size()); -} - -void Bomb::launch(Bomb::Direction direction) -{ - launchAnimation = new QSequentialAnimationGroup(); - AnimationManager::self()->registerAnimation(launchAnimation); - qreal delta = direction == Right ? 20 : - 20; - QPropertyAnimation *anim = new QPropertyAnimation(this, "pos"); - anim->setEndValue(QPointF(x() + delta,y() - 20)); - anim->setDuration(150); - launchAnimation->addAnimation(anim); - anim = new QPropertyAnimation(this, "pos"); - anim->setEndValue(QPointF(x() + delta*2, y() )); - anim->setDuration(150); - launchAnimation->addAnimation(anim); - anim = new QPropertyAnimation(this, "pos"); - anim->setEndValue(QPointF(x() + delta*2,scene()->height())); - anim->setDuration(y()/2*60); - launchAnimation->addAnimation(anim); - connect(anim,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationLaunchValueChanged(const QVariant &))); - - //We setup the state machine of the bomb - QStateMachine *machine = new QStateMachine(this); - - //This state is when the launch animation is playing - QAnimationState *launched = new QAnimationState(machine->rootState()); - launched->setAnimation(launchAnimation); - - //End - QFinalState *final = new QFinalState(machine->rootState()); - - machine->setInitialState(launched); - - //### Add a nice animation when the bomb is destroyed - launched->addTransition(this, SIGNAL(bombExplosed()),final); - - //If the animation is finished, then we move to the final state - launched->addTransition(launched, SIGNAL(animationFinished()), final); - - //The machine has finished to be executed, then the boat is dead - connect(machine,SIGNAL(finished()),this, SIGNAL(bombExecutionFinished())); - - machine->start(); - -} - -void Bomb::onAnimationLaunchValueChanged(const QVariant &) -{ - foreach (QGraphicsItem * item , collidingItems(Qt::IntersectsItemBoundingRect)) { - if (item->type() == SubMarine::Type) { - SubMarine *s = static_cast(item); - destroy(); - s->destroy(); - } - } -} - -void Bomb::destroy() -{ - launchAnimation->stop(); - emit bombExplosed(); -} diff --git a/examples/animation/sub-attaq/bomb.h b/examples/animation/sub-attaq/bomb.h deleted file mode 100644 index 226d056..0000000 --- a/examples/animation/sub-attaq/bomb.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __BOMB__H__ -#define __BOMB__H__ - -//Qt -#include -#include - -class PixmapItem; - -class Bomb : public QGraphicsWidget -{ -Q_OBJECT -Q_PROPERTY(QPointF pos READ pos WRITE setPos) -public: - enum Direction { - Left = 0, - Right - }; - Bomb(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); - void launch(Direction direction); - void destroy(); - -Q_SIGNALS: - void bombExplosed(); - void bombExecutionFinished(); - -private slots: - void onAnimationLaunchValueChanged(const QVariant &); - -private: - QAnimationGroup *launchAnimation; - PixmapItem *pixmapItem; -}; - -#endif //__BOMB__H__ diff --git a/examples/animation/sub-attaq/custompropertyanimation.cpp b/examples/animation/sub-attaq/custompropertyanimation.cpp deleted file mode 100644 index 8226cca..0000000 --- a/examples/animation/sub-attaq/custompropertyanimation.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "custompropertyanimation.h" - -// Qt -#include - -CustomPropertyAnimation::CustomPropertyAnimation(QObject *parent) : - QVariantAnimation(parent), animProp(0) -{ -} - -CustomPropertyAnimation::~CustomPropertyAnimation() -{ -} - -void CustomPropertyAnimation::setProperty(AbstractProperty *_animProp) -{ - if (animProp == _animProp) - return; - delete animProp; - animProp = _animProp; -} - -/*! - \reimp - */ -void CustomPropertyAnimation::updateCurrentValue(const QVariant &value) -{ - if (!animProp || state() == QAbstractAnimation::Stopped) - return; - - animProp->write(value); -} - - -/*! - \reimp -*/ -void CustomPropertyAnimation::updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState) -{ - // Initialize start value - if (oldState == QAbstractAnimation::Stopped) { - if (!animProp) - return; - QVariant def = animProp->read(); - if (def.isValid()) { - const int t = def.userType(); - KeyValues values = keyValues(); - //this ensures that all the keyValues are of type t - for (int i = 0; i < values.count(); ++i) { - QVariantAnimation::KeyValue &pair = values[i]; - if (pair.second.userType() != t) - pair.second.convert(static_cast(t)); - } - //let's now update the key values - setKeyValues(values); - } - - if (animProp && !startValue().isValid() && currentTime() == 0 - || (currentTime() == duration() && currentLoop() == (loopCount() - 1))) { - setStartValue(def); - } - } - - QVariantAnimation::updateState(oldState, newState); -} - -#include "moc_custompropertyanimation.cpp" diff --git a/examples/animation/sub-attaq/custompropertyanimation.h b/examples/animation/sub-attaq/custompropertyanimation.h deleted file mode 100644 index 8654aeb..0000000 --- a/examples/animation/sub-attaq/custompropertyanimation.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CUSTOMPROPERTYANIMATION_H -#define CUSTOMPROPERTYANIMATION_H - -#include - -QT_BEGIN_NAMESPACE -class QGraphicsItem; -QT_END_NAMESPACE - -struct AbstractProperty -{ - virtual QVariant read() const = 0; - virtual void write(const QVariant &value) = 0; -}; - - -class CustomPropertyAnimation : public QVariantAnimation -{ - Q_OBJECT - - template - class MemberFunctionProperty : public AbstractProperty - { - public: - typedef T (Target::*Getter)(void) const; - typedef void (Target::*Setter)(T2); - - MemberFunctionProperty(Target* target, Getter getter, Setter setter) - : m_target(target), m_getter(getter), m_setter(setter) {} - - virtual void write(const QVariant &value) - { - if (m_setter) (m_target->*m_setter)(qVariantValue(value)); - } - - virtual QVariant read() const - { - if (m_getter) return qVariantFromValue((m_target->*m_getter)()); - return QVariant(); - } - - private: - Target *m_target; - Getter m_getter; - Setter m_setter; - }; - -public: - CustomPropertyAnimation(QObject *parent = 0); - ~CustomPropertyAnimation(); - - template - void setMemberFunctions(Target* target, T (Target::*getter)() const, void (Target::*setter)(const T& )) - { - setProperty(new MemberFunctionProperty(target, getter, setter)); - } - - template - void setMemberFunctions(Target* target, T (Target::*getter)() const, void (Target::*setter)(T)) - { - setProperty(new MemberFunctionProperty(target, getter, setter)); - } - - void updateCurrentValue(const QVariant &value); - void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - void setProperty(AbstractProperty *animProp); - -private: - Q_DISABLE_COPY(CustomPropertyAnimation); - AbstractProperty *animProp; -}; - -#endif // CUSTOMPROPERTYANIMATION_H diff --git a/examples/animation/sub-attaq/data.xml b/examples/animation/sub-attaq/data.xml deleted file mode 100644 index 41d4754..0000000 --- a/examples/animation/sub-attaq/data.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/graphicsscene.cpp b/examples/animation/sub-attaq/graphicsscene.cpp deleted file mode 100644 index f2d41bc..0000000 --- a/examples/animation/sub-attaq/graphicsscene.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//Own -#include "graphicsscene.h" -#include "states.h" -#include "boat.h" -#include "submarine.h" -#include "torpedo.h" -#include "bomb.h" -#include "pixmapitem.h" -#include "custompropertyanimation.h" -#include "animationmanager.h" -#include "qanimationstate.h" -#include "progressitem.h" - -//Qt -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//helper function that creates an animation for position and inserts it into group -static CustomPropertyAnimation *addGraphicsItemPosAnimation(QSequentialAnimationGroup *group, - QGraphicsItem *item, const QPointF &endPos) -{ - CustomPropertyAnimation *ret = new CustomPropertyAnimation(group); - ret->setMemberFunctions(item, &QGraphicsItem::pos, &QGraphicsItem::setPos); - ret->setEndValue(endPos); - ret->setDuration(200); - ret->setEasingCurve(QEasingCurve::OutElastic); - group->addPause(50); - return ret; -} - -//helper function that creates an animation for opacity and inserts it into group -static void addGraphicsItemFadeoutAnimation(QAnimationGroup *group, QGraphicsItem *item) -{ -#if QT_VERSION >=0x040500 - CustomPropertyAnimation *anim = new CustomPropertyAnimation(group); - anim->setMemberFunctions(item, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim->setDuration(800); - anim->setEndValue(0); - anim->setEasingCurve(QEasingCurve::OutQuad); -#else - // work around for a bug where we don't transition if the duration is zero. - QtPauseAnimation *anim = new QtPauseAnimation(group); - anim->setDuration(1); -#endif -} - -GraphicsScene::GraphicsScene(int x, int y, int width, int height, Mode mode) - : QGraphicsScene(x,y,width,height), mode(mode), newAction(0), quitAction(0), boat(0) -{ - backgroundItem = new PixmapItem(QString("background"),mode); - backgroundItem->setZValue(1); - backgroundItem->setPos(0,0); - addItem(backgroundItem); - - PixmapItem *surfaceItem = new PixmapItem(QString("surface"),mode); - surfaceItem->setZValue(3); - surfaceItem->setPos(0,sealLevel() - surfaceItem->boundingRect().height()/2); - addItem(surfaceItem); - - //The item that display score and level - progressItem = new ProgressItem(backgroundItem); - - //We create the boat - boat = new Boat(); - addItem(boat); - boat->setPos(this->width()/2, sealLevel() - boat->size().height()); - boat->hide(); - - //parse the xml that contain all data of the game - QXmlStreamReader reader; - QFile file(QDir::currentPath() + "/data.xml"); - file.open(QIODevice::ReadOnly); - reader.setDevice(&file); - LevelDescription currentLevel; - while (!reader.atEnd()) { - reader.readNext(); - if (reader.tokenType() == QXmlStreamReader::StartElement) { - if (reader.name() == "submarine") - { - SubmarineDescription desc; - desc.name = reader.attributes().value("name").toString(); - desc.points = reader.attributes().value("points").toString().toInt(); - desc.type = reader.attributes().value("type").toString().toInt(); - submarinesData.append(desc); - } - if (reader.name() == "level") - { - currentLevel.id = reader.attributes().value("id").toString().toInt(); - currentLevel.name = reader.attributes().value("name").toString(); - } - if (reader.name() == "subinstance") - { - currentLevel.submarines.append(qMakePair(reader.attributes().value("type").toString().toInt(),reader.attributes().value("nb").toString().toInt())); - } - } - if (reader.tokenType() == QXmlStreamReader::EndElement) { - if (reader.name() == "level") - { - levelsData.insert(currentLevel.id,currentLevel); - currentLevel.submarines.clear(); - } - } - } -} - -qreal GraphicsScene::sealLevel() const -{ - if (mode == Big) - return 220; - else - return 160; -} - -void GraphicsScene::setupScene(const QList &actions) -{ - newAction = actions.at(0); - quitAction = actions.at(1); - - QGraphicsItem *logo_s = addWelcomeItem(QPixmap(":/logo-s")); - QGraphicsItem *logo_u = addWelcomeItem(QPixmap(":/logo-u")); - QGraphicsItem *logo_b = addWelcomeItem(QPixmap(":/logo-b")); - QGraphicsItem *logo_dash = addWelcomeItem(QPixmap(":/logo-dash")); - QGraphicsItem *logo_a = addWelcomeItem(QPixmap(":/logo-a")); - QGraphicsItem *logo_t = addWelcomeItem(QPixmap(":/logo-t")); - QGraphicsItem *logo_t2 = addWelcomeItem(QPixmap(":/logo-t2")); - QGraphicsItem *logo_a2 = addWelcomeItem(QPixmap(":/logo-a2")); - QGraphicsItem *logo_q = addWelcomeItem(QPixmap(":/logo-q")); - QGraphicsItem *logo_excl = addWelcomeItem(QPixmap(":/logo-excl")); - logo_s->setZValue(3); - logo_u->setZValue(4); - logo_b->setZValue(5); - logo_dash->setZValue(6); - logo_a->setZValue(7); - logo_t->setZValue(8); - logo_t2->setZValue(9); - logo_a2->setZValue(10); - logo_q->setZValue(11); - logo_excl->setZValue(12); - logo_s->setPos(QPointF(-1000, -1000)); - logo_u->setPos(QPointF(-800, -1000)); - logo_b->setPos(QPointF(-600, -1000)); - logo_dash->setPos(QPointF(-400, -1000)); - logo_a->setPos(QPointF(1000, 2000)); - logo_t->setPos(QPointF(800, 2000)); - logo_t2->setPos(QPointF(600, 2000)); - logo_a2->setPos(QPointF(400, 2000)); - logo_q->setPos(QPointF(200, 2000)); - logo_excl->setPos(QPointF(0, 2000)); - - QSequentialAnimationGroup * lettersGroupMoving = new QSequentialAnimationGroup(this); - QParallelAnimationGroup * lettersGroupFading = new QParallelAnimationGroup(this); - - //creation of the animations for moving letters - addGraphicsItemPosAnimation(lettersGroupMoving, logo_s, QPointF(300, 150)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_u, QPointF(350, 150)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_b, QPointF(400, 120)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_dash, QPointF(460, 150)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_a, QPointF(350, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_t, QPointF(400, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_t2, QPointF(430, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_a2, QPointF(465, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_q, QPointF(510, 250)); - addGraphicsItemPosAnimation(lettersGroupMoving, logo_excl, QPointF(570, 220)); - - //creation of the animations for fading out the letters - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_s); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_u); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_b); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_dash); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_a); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_t); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_t2); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_a2); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_q); - addGraphicsItemFadeoutAnimation(lettersGroupFading, logo_excl); - connect(lettersGroupFading, SIGNAL(finished()), this, SLOT(onIntroAnimationFinished())); - - QStateMachine *machine = new QStateMachine(this); - - //This state is when the player is playing - PlayState *gameState = new PlayState(this,machine->rootState()); - - //Final state - QFinalState *final = new QFinalState(machine->rootState()); - - //Animation when the player enter in the game - QAnimationState *lettersMovingState = new QAnimationState(machine->rootState()); - lettersMovingState->setAnimation(lettersGroupMoving); - - //Animation when the welcome screen disappear - QAnimationState *lettersFadingState = new QAnimationState(machine->rootState()); - lettersFadingState->setAnimation(lettersGroupFading); - - //if new game then we fade out the welcome screen and start playing - lettersMovingState->addTransition(newAction, SIGNAL(triggered()),lettersFadingState); - lettersFadingState->addTransition(lettersFadingState, SIGNAL(animationFinished()),gameState); - - //New Game is triggered then player start playing - gameState->addTransition(newAction, SIGNAL(triggered()),gameState); - - //Wanna quit, then connect to CTRL+Q - gameState->addTransition(quitAction, SIGNAL(triggered()),final); - lettersMovingState->addTransition(quitAction, SIGNAL(triggered()),final); - - //Welcome screen is the initial state - machine->setInitialState(lettersMovingState); - - machine->start(); - - //We reach the final state, then we quit - connect(machine,SIGNAL(finished()),this, SLOT(onQuitGameTriggered())); -} - -void GraphicsScene::addItem(Bomb *bomb) -{ - bombs.insert(bomb); - connect(bomb,SIGNAL(bombExecutionFinished()),this, SLOT(onBombExecutionFinished())); - QGraphicsScene::addItem(bomb); -} - -void GraphicsScene::addItem(Torpedo *torpedo) -{ - torpedos.insert(torpedo); - connect(torpedo,SIGNAL(torpedoExecutionFinished()),this, SLOT(onTorpedoExecutionFinished())); - QGraphicsScene::addItem(torpedo); -} - -void GraphicsScene::addItem(SubMarine *submarine) -{ - submarines.insert(submarine); - connect(submarine,SIGNAL(subMarineExecutionFinished()),this, SLOT(onSubMarineExecutionFinished())); - QGraphicsScene::addItem(submarine); -} - -void GraphicsScene::addItem(QGraphicsItem *item) -{ - QGraphicsScene::addItem(item); -} - -void GraphicsScene::mousePressEvent (QGraphicsSceneMouseEvent * event) -{ - event->ignore(); -} - -void GraphicsScene::onQuitGameTriggered() -{ - qApp->closeAllWindows(); -} - -void GraphicsScene::onBombExecutionFinished() -{ - Bomb *bomb = qobject_cast(sender()); - bombs.remove(bomb); - bomb->deleteLater(); - if (boat) - boat->setBombsLaunched(boat->bombsLaunched() - 1); -} - -void GraphicsScene::onTorpedoExecutionFinished() -{ - Torpedo *torpedo = qobject_cast(sender()); - torpedos.remove(torpedo); - torpedo->deleteLater(); -} - -void GraphicsScene::onSubMarineExecutionFinished() -{ - SubMarine *submarine = qobject_cast(sender()); - submarines.remove(submarine); - if (submarines.count() == 0) { - emit allSubMarineDestroyed(submarine->points()); - } else { - emit subMarineDestroyed(submarine->points()); - } - submarine->deleteLater(); -} - -int GraphicsScene::remainingSubMarines() const -{ - return submarines.count(); -} - -void GraphicsScene::clearScene() -{ - foreach (SubMarine *sub,submarines) { - sub->destroy(); - sub->deleteLater(); - } - - foreach (Torpedo *torpedo,torpedos) { - torpedo->destroy(); - torpedo->deleteLater(); - } - - foreach (Bomb *bomb,bombs) { - bomb->destroy(); - bomb->deleteLater(); - } - - submarines.clear(); - bombs.clear(); - torpedos.clear(); - - AnimationManager::self()->unregisterAllAnimations(); - - boat->stop(); - boat->hide(); -} - -QGraphicsPixmapItem *GraphicsScene::addWelcomeItem(const QPixmap &pm) -{ - QGraphicsPixmapItem *item = addPixmap(pm); - welcomeItems << item; - return item; -} - -void GraphicsScene::onIntroAnimationFinished() -{ - qDeleteAll(welcomeItems); - welcomeItems.clear(); -} - diff --git a/examples/animation/sub-attaq/graphicsscene.h b/examples/animation/sub-attaq/graphicsscene.h deleted file mode 100644 index 8b0ea96..0000000 --- a/examples/animation/sub-attaq/graphicsscene.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __GRAPHICSSCENE__H__ -#define __GRAPHICSSCENE__H__ - -//Qt -#include -#include -#include - - -class Boat; -class SubMarine; -class Torpedo; -class Bomb; -class PixmapItem; -class ProgressItem; -QT_BEGIN_NAMESPACE -class QAction; -QT_END_NAMESPACE - -class GraphicsScene : public QGraphicsScene -{ -Q_OBJECT -public: - enum Mode { - Big = 0, - Small - }; - - struct SubmarineDescription { - int type; - int points; - QString name; - }; - - struct LevelDescription { - int id; - QString name; - QList > submarines; - }; - - GraphicsScene(int x, int y, int width, int height, Mode mode = Big); - qreal sealLevel() const; - void setupScene(const QList &actions); - void addItem(Bomb *bomb); - void addItem(Torpedo *torpedo); - void addItem(SubMarine *submarine); - void addItem(QGraphicsItem *item); - int remainingSubMarines() const; - void clearScene(); - QGraphicsPixmapItem *addWelcomeItem(const QPixmap &pm); - -Q_SIGNALS: - void subMarineDestroyed(int); - void allSubMarineDestroyed(int); - -protected: - void mousePressEvent (QGraphicsSceneMouseEvent * event); - -private slots: - void onQuitGameTriggered(); - void onBombExecutionFinished(); - void onTorpedoExecutionFinished(); - void onSubMarineExecutionFinished(); - void onIntroAnimationFinished(); - -private: - Mode mode; - PixmapItem *backgroundItem; - ProgressItem *progressItem; - QAction * newAction; - QAction * quitAction; - Boat *boat; - QSet submarines; - QSet bombs; - QSet torpedos; - QVector welcomeItems; - QVector submarinesData; - QHash levelsData; - - friend class PauseState; - friend class PlayState; - friend class LevelState; - friend class LostState; - friend class WinState; - friend class WinTransition; - friend class UpdateScoreTransition; -}; - -#endif //__GRAPHICSSCENE__H__ - diff --git a/examples/animation/sub-attaq/main.cpp b/examples/animation/sub-attaq/main.cpp deleted file mode 100644 index ffaa86f..0000000 --- a/examples/animation/sub-attaq/main.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "mainwindow.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - Q_INIT_RESOURCE(subattaq); - - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - - MainWindow w; - w.show(); - - return app.exec(); -} diff --git a/examples/animation/sub-attaq/mainwindow.cpp b/examples/animation/sub-attaq/mainwindow.cpp deleted file mode 100644 index a166241..0000000 --- a/examples/animation/sub-attaq/mainwindow.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//Own -#include "mainwindow.h" -#include "graphicsscene.h" - -#ifndef QT_NO_OPENGL - #include -#endif -//Qt -#include - -MainWindow::MainWindow() : QMainWindow(0) -{ - QMenuBar *menuBar = new QMenuBar; - QMenu *file = new QMenu(tr("&File"),menuBar); - - QAction *newAction = new QAction(tr("New Game"),file); - newAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N)); - file->addAction(newAction); - QAction *quitAction = new QAction(tr("Quit"),file); - quitAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q)); - file->addAction(quitAction); - - menuBar->addMenu(file); - setMenuBar(menuBar); - - QStringList list = QApplication::arguments(); - if (list.contains("-fullscreen")) { - scene = new GraphicsScene(0, 0, 750, 400,GraphicsScene::Small); - setWindowState(Qt::WindowFullScreen); - } else { - scene = new GraphicsScene(0, 0, 880, 630); - layout()->setSizeConstraint(QLayout::SetFixedSize); - } - - view = new QGraphicsView(scene,this); - view->setAlignment(Qt::AlignLeft | Qt::AlignTop); - QList actions; - actions << newAction << quitAction; - scene->setupScene(actions); -#ifndef QT_NO_OPENGL - view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); -#endif - - setCentralWidget(view); - -} - -MainWindow::~MainWindow() -{ -} - diff --git a/examples/animation/sub-attaq/mainwindow.h b/examples/animation/sub-attaq/mainwindow.h deleted file mode 100644 index 87f194a..0000000 --- a/examples/animation/sub-attaq/mainwindow.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __MAINWINDOW__H__ -#define __MAINWINDOW__H__ - -//Qt -#include -class GraphicsScene; -QT_BEGIN_NAMESPACE -class QGraphicsView; -QT_END_NAMESPACE - -class MainWindow : public QMainWindow -{ -Q_OBJECT -public: - MainWindow(); - ~MainWindow(); - -private: - GraphicsScene *scene; - QGraphicsView *view; -}; - -#endif //__MAINWINDOW__H__ diff --git a/examples/animation/sub-attaq/pics/big/background.png b/examples/animation/sub-attaq/pics/big/background.png deleted file mode 100644 index 9f58157..0000000 Binary files a/examples/animation/sub-attaq/pics/big/background.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/boat.png b/examples/animation/sub-attaq/pics/big/boat.png deleted file mode 100644 index be82dff..0000000 Binary files a/examples/animation/sub-attaq/pics/big/boat.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/bomb.png b/examples/animation/sub-attaq/pics/big/bomb.png deleted file mode 100644 index 3af5f2f..0000000 Binary files a/examples/animation/sub-attaq/pics/big/bomb.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png deleted file mode 100644 index c9fd8b0..0000000 Binary files a/examples/animation/sub-attaq/pics/big/explosion/boat/step1.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png deleted file mode 100644 index 7528f2d..0000000 Binary files a/examples/animation/sub-attaq/pics/big/explosion/boat/step2.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png deleted file mode 100644 index aae9c9c..0000000 Binary files a/examples/animation/sub-attaq/pics/big/explosion/boat/step3.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png b/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png deleted file mode 100644 index d697c1b..0000000 Binary files a/examples/animation/sub-attaq/pics/big/explosion/boat/step4.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png deleted file mode 100644 index 88ca514..0000000 Binary files a/examples/animation/sub-attaq/pics/big/explosion/submarine/step1.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png deleted file mode 100644 index 524f589..0000000 Binary files a/examples/animation/sub-attaq/pics/big/explosion/submarine/step2.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png deleted file mode 100644 index 2cca1e8..0000000 Binary files a/examples/animation/sub-attaq/pics/big/explosion/submarine/step3.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png b/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png deleted file mode 100644 index 82100a8..0000000 Binary files a/examples/animation/sub-attaq/pics/big/explosion/submarine/step4.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/submarine.png b/examples/animation/sub-attaq/pics/big/submarine.png deleted file mode 100644 index df435dc..0000000 Binary files a/examples/animation/sub-attaq/pics/big/submarine.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/surface.png b/examples/animation/sub-attaq/pics/big/surface.png deleted file mode 100644 index 4eba29e..0000000 Binary files a/examples/animation/sub-attaq/pics/big/surface.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/big/torpedo.png b/examples/animation/sub-attaq/pics/big/torpedo.png deleted file mode 100644 index f9c2687..0000000 Binary files a/examples/animation/sub-attaq/pics/big/torpedo.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/scalable/background-n810.svg b/examples/animation/sub-attaq/pics/scalable/background-n810.svg deleted file mode 100644 index ece9f7a..0000000 --- a/examples/animation/sub-attaq/pics/scalable/background-n810.svg +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/background.svg b/examples/animation/sub-attaq/pics/scalable/background.svg deleted file mode 100644 index 0be2680..0000000 --- a/examples/animation/sub-attaq/pics/scalable/background.svg +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/boat.svg b/examples/animation/sub-attaq/pics/scalable/boat.svg deleted file mode 100644 index 5298821b..0000000 --- a/examples/animation/sub-attaq/pics/scalable/boat.svg +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/bomb.svg b/examples/animation/sub-attaq/pics/scalable/bomb.svg deleted file mode 100644 index 294771a..0000000 --- a/examples/animation/sub-attaq/pics/scalable/bomb.svg +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/sand.svg b/examples/animation/sub-attaq/pics/scalable/sand.svg deleted file mode 100644 index 8af11b7..0000000 --- a/examples/animation/sub-attaq/pics/scalable/sand.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/see.svg b/examples/animation/sub-attaq/pics/scalable/see.svg deleted file mode 100644 index 0666691..0000000 --- a/examples/animation/sub-attaq/pics/scalable/see.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/sky.svg b/examples/animation/sub-attaq/pics/scalable/sky.svg deleted file mode 100644 index 1546c08..0000000 --- a/examples/animation/sub-attaq/pics/scalable/sky.svg +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg b/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg deleted file mode 100644 index b075179..0000000 --- a/examples/animation/sub-attaq/pics/scalable/sub-attaq.svg +++ /dev/null @@ -1,1473 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/submarine.svg b/examples/animation/sub-attaq/pics/scalable/submarine.svg deleted file mode 100644 index 8a0ffdd..0000000 --- a/examples/animation/sub-attaq/pics/scalable/submarine.svg +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/surface.svg b/examples/animation/sub-attaq/pics/scalable/surface.svg deleted file mode 100644 index 40ed239..0000000 --- a/examples/animation/sub-attaq/pics/scalable/surface.svg +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/scalable/torpedo.svg b/examples/animation/sub-attaq/pics/scalable/torpedo.svg deleted file mode 100644 index 48e429d..0000000 --- a/examples/animation/sub-attaq/pics/scalable/torpedo.svg +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/animation/sub-attaq/pics/small/background.png b/examples/animation/sub-attaq/pics/small/background.png deleted file mode 100644 index 5ad3db6..0000000 Binary files a/examples/animation/sub-attaq/pics/small/background.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/small/boat.png b/examples/animation/sub-attaq/pics/small/boat.png deleted file mode 100644 index 114ccc3..0000000 Binary files a/examples/animation/sub-attaq/pics/small/boat.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/small/bomb.png b/examples/animation/sub-attaq/pics/small/bomb.png deleted file mode 100644 index 3af5f2f..0000000 Binary files a/examples/animation/sub-attaq/pics/small/bomb.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/small/submarine.png b/examples/animation/sub-attaq/pics/small/submarine.png deleted file mode 100644 index 0c0c350..0000000 Binary files a/examples/animation/sub-attaq/pics/small/submarine.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/small/surface.png b/examples/animation/sub-attaq/pics/small/surface.png deleted file mode 100644 index 06d0e47..0000000 Binary files a/examples/animation/sub-attaq/pics/small/surface.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/small/torpedo.png b/examples/animation/sub-attaq/pics/small/torpedo.png deleted file mode 100644 index f9c2687..0000000 Binary files a/examples/animation/sub-attaq/pics/small/torpedo.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-a.png b/examples/animation/sub-attaq/pics/welcome/logo-a.png deleted file mode 100644 index 67dd76d..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-a.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-a2.png b/examples/animation/sub-attaq/pics/welcome/logo-a2.png deleted file mode 100644 index 17668b0..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-a2.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-b.png b/examples/animation/sub-attaq/pics/welcome/logo-b.png deleted file mode 100644 index cf6c045..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-b.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-dash.png b/examples/animation/sub-attaq/pics/welcome/logo-dash.png deleted file mode 100644 index 219233c..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-dash.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-excl.png b/examples/animation/sub-attaq/pics/welcome/logo-excl.png deleted file mode 100644 index 8dd0a2e..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-excl.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-q.png b/examples/animation/sub-attaq/pics/welcome/logo-q.png deleted file mode 100644 index 86e588d..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-q.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-s.png b/examples/animation/sub-attaq/pics/welcome/logo-s.png deleted file mode 100644 index 7b6a36e..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-s.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-t.png b/examples/animation/sub-attaq/pics/welcome/logo-t.png deleted file mode 100644 index b2e3526..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-t.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-t2.png b/examples/animation/sub-attaq/pics/welcome/logo-t2.png deleted file mode 100644 index b11a778..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-t2.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pics/welcome/logo-u.png b/examples/animation/sub-attaq/pics/welcome/logo-u.png deleted file mode 100644 index 24eede8..0000000 Binary files a/examples/animation/sub-attaq/pics/welcome/logo-u.png and /dev/null differ diff --git a/examples/animation/sub-attaq/pixmapitem.cpp b/examples/animation/sub-attaq/pixmapitem.cpp deleted file mode 100644 index 22a363f..0000000 --- a/examples/animation/sub-attaq/pixmapitem.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//Own -#include "pixmapitem.h" - -//Qt -#include - -PixmapItem::PixmapItem(const QString &fileName,GraphicsScene::Mode mode, QGraphicsItem * parent) : QGraphicsPixmapItem(parent),name(fileName) -{ - loadPixmap(mode); -} - -void PixmapItem::loadPixmap(GraphicsScene::Mode mode) -{ - if (mode == GraphicsScene::Big) - setPixmap(":/big/" + name); - else - setPixmap(":/small/" + name); -} diff --git a/examples/animation/sub-attaq/pixmapitem.h b/examples/animation/sub-attaq/pixmapitem.h deleted file mode 100644 index 31022c1..0000000 --- a/examples/animation/sub-attaq/pixmapitem.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __PIXMAPITEM__H__ -#define __PIXMAPITEM__H__ - -//Own -#include "graphicsscene.h" - -//Qt -#include - -class PixmapItem : public QGraphicsPixmapItem -{ -public: - PixmapItem(const QString &fileName, GraphicsScene::Mode mode, QGraphicsItem * parent = 0); - -private: - void loadPixmap(GraphicsScene::Mode mode); - - QString name; - QPixmap pixmap; -}; - -#endif //__PIXMAPITEM__H__ diff --git a/examples/animation/sub-attaq/progressitem.cpp b/examples/animation/sub-attaq/progressitem.cpp deleted file mode 100644 index 59ccb9a..0000000 --- a/examples/animation/sub-attaq/progressitem.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "progressitem.h" -#include "pixmapitem.h" - -ProgressItem::ProgressItem (QGraphicsItem * parent) - : QGraphicsTextItem(parent), currentLevel(1), currentScore(0) -{ - setFont(QFont("Comic Sans MS")); - setPos(parentItem()->boundingRect().topRight() - QPointF(180, -5)); -} - -void ProgressItem::setLevel(int level) -{ - currentLevel = level; - updateProgress(); -} - -void ProgressItem::setScore(int score) -{ - currentScore = score; - updateProgress(); -} - -void ProgressItem::updateProgress() -{ - setHtml(QString("Level : %1 Score : %2").arg(currentLevel).arg(currentScore)); -} diff --git a/examples/animation/sub-attaq/progressitem.h b/examples/animation/sub-attaq/progressitem.h deleted file mode 100644 index 7b8db4d..0000000 --- a/examples/animation/sub-attaq/progressitem.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PROGRESSITEM_H -#define PROGRESSITEM_H - -//Qt -#include - -class ProgressItem : public QGraphicsTextItem -{ -public: - ProgressItem(QGraphicsItem * parent = 0); - void setLevel(int level); - void setScore(int score); - -private: - void updateProgress(); - int currentLevel; - int currentScore; -}; - -#endif // PROGRESSITEM_H diff --git a/examples/animation/sub-attaq/qanimationstate.cpp b/examples/animation/sub-attaq/qanimationstate.cpp deleted file mode 100644 index 26e0ef3..0000000 --- a/examples/animation/sub-attaq/qanimationstate.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qanimationstate.h" - -#include -#include - - -QT_BEGIN_NAMESPACE - -/*! -\class QAnimationState - -\brief The QAnimationState class provides state that handle an animation and emit -a signal when this animation is finished. - -\ingroup statemachine - -QAnimationState provides a state that handle an animation. It will start this animation -when the state is entered and stop it when it is leaved. When the animation has finished the -state emit animationFinished signal. -QAnimationState is part of \l{The State Machine Framework}. - -\code -QStateMachine machine; -QAnimationState *s = new QAnimationState(machine->rootState()); -QPropertyAnimation *animation = new QPropertyAnimation(obj, "pos"); -s->setAnimation(animation); -QState *s2 = new QState(machine->rootState()); -s->addTransition(s, SIGNAL(animationFinished()), s2); -machine.start(); -\endcode - -\sa QState, {The Animation Framework} -*/ - - -#ifndef QT_NO_ANIMATION - -class QAnimationStatePrivate : public QStatePrivate -{ - Q_DECLARE_PUBLIC(QAnimationState) -public: - QAnimationStatePrivate() - : animation(0) - { - - } - ~QAnimationStatePrivate() {} - - QAbstractAnimation *animation; -}; - -/*! - Constructs a new state with the given \a parent state. -*/ -QAnimationState::QAnimationState(QState *parent) - : QState(*new QAnimationStatePrivate, parent) -{ -} - -/*! - Destroys the animation state. -*/ -QAnimationState::~QAnimationState() -{ -} - -/*! - Set an \a animation for this QAnimationState. If an animation was previously handle by this - state then it won't emit animationFinished for the old animation. The QAnimationState doesn't - take the ownership of the animation. -*/ -void QAnimationState::setAnimation(QAbstractAnimation *animation) -{ - Q_D(QAnimationState); - - if (animation == d->animation) - return; - - //Disconnect from the previous animation if exist - if(d->animation) - disconnect(d->animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); - - d->animation = animation; - - if (d->animation) { - //connect the new animation - connect(d->animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); - } -} - -/*! - Returns the animation handle by this animation state, or 0 if there is no animation. -*/ -QAbstractAnimation* QAnimationState::animation() const -{ - Q_D(const QAnimationState); - return d->animation; -} - -/*! - \reimp -*/ -void QAnimationState::onEntry(QEvent *) -{ - Q_D(QAnimationState); - if (d->animation) - d->animation->start(); -} - -/*! - \reimp -*/ -void QAnimationState::onExit(QEvent *) -{ - Q_D(QAnimationState); - if (d->animation) - d->animation->stop(); -} - -/*! - \reimp -*/ -bool QAnimationState::event(QEvent *e) -{ - return QState::event(e); -} - -QT_END_NAMESPACE - -#endif diff --git a/examples/animation/sub-attaq/qanimationstate.h b/examples/animation/sub-attaq/qanimationstate.h deleted file mode 100644 index 88c0a6d..0000000 --- a/examples/animation/sub-attaq/qanimationstate.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANIMATIONSTATE_H -#define QANIMATIONSTATE_H - -#ifndef QT_STATEMACHINE_SOLUTION -# include -# include -#else -# include "qstate.h" -# include "qabstractanimation.h" -#endif - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_ANIMATION - -class QAnimationStatePrivate; - -class QAnimationState : public QState -{ - Q_OBJECT -public: - QAnimationState(QState *parent = 0); - ~QAnimationState(); - - void setAnimation(QAbstractAnimation *animation); - QAbstractAnimation* animation() const; - -Q_SIGNALS: - void animationFinished(); - -protected: - void onEntry(QEvent *); - void onExit(QEvent *); - bool event(QEvent *e); - -private: - Q_DISABLE_COPY(QAnimationState) - Q_DECLARE_PRIVATE(QAnimationState) -}; - -#endif - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QANIMATIONSTATE_H diff --git a/examples/animation/sub-attaq/states.cpp b/examples/animation/sub-attaq/states.cpp deleted file mode 100644 index adc8bd0..0000000 --- a/examples/animation/sub-attaq/states.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//Own -#include "states.h" -#include "graphicsscene.h" -#include "boat.h" -#include "submarine.h" -#include "torpedo.h" -#include "animationmanager.h" -#include "progressitem.h" - -//Qt -#include -#include -#include -#include -#include -#include - -PlayState::PlayState(GraphicsScene *scene, QState *parent) - : QState(parent), - scene(scene), - machine(0), - currentLevel(0), - score(0) -{ -} - -PlayState::~PlayState() -{ -} - -void PlayState::onEntry(QEvent *) -{ - //We are now playing? - if (machine) { - machine->stop(); - scene->clearScene(); - currentLevel = 0; - score = 0; - delete machine; - } - - machine = new QStateMachine(this); - - //This state is when player is playing - LevelState *levelState = new LevelState(scene, this, machine->rootState()); - - //This state is when the player is actually playing but the game is not paused - QState *playingState = new QState(levelState); - levelState->setInitialState(playingState); - - //This state is when the game is paused - PauseState *pauseState = new PauseState(scene, levelState); - - //We have one view, it receive the key press event - QKeyEventTransition *pressPplay = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P); - pressPplay->setTargetState(pauseState); - QKeyEventTransition *pressPpause = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P); - pressPpause->setTargetState(playingState); - - //Pause "P" is triggered, the player pause the game - playingState->addTransition(pressPplay); - - //To get back playing when the game has been paused - pauseState->addTransition(pressPpause); - - //This state is when player have lost - LostState *lostState = new LostState(scene, this, machine->rootState()); - - //This state is when player have won - WinState *winState = new WinState(scene, this, machine->rootState()); - - //The boat has been destroyed then the game is finished - levelState->addTransition(scene->boat, SIGNAL(boatExecutionFinished()),lostState); - - //This transition check if we won or not - WinTransition *winTransition = new WinTransition(scene, this, winState); - - //The boat has been destroyed then the game is finished - levelState->addTransition(winTransition); - - //This state is an animation when the score changed - UpdateScoreState *scoreState = new UpdateScoreState(this, levelState); - - //This transition update the score when a submarine die - UpdateScoreTransition *scoreTransition = new UpdateScoreTransition(scene, this, levelState); - scoreTransition->setTargetState(scoreState); - - //The boat has been destroyed then the game is finished - playingState->addTransition(scoreTransition); - - //We go back to play state - scoreState->addTransition(playingState); - - //We start playing!!! - machine->setInitialState(levelState); - - //Final state - QFinalState *final = new QFinalState(machine->rootState()); - - //This transition is triggered when the player press space after completing a level - CustomSpaceTransition *spaceTransition = new CustomSpaceTransition(scene->views().at(0), this, QEvent::KeyPress, Qt::Key_Space); - spaceTransition->setTargetState(levelState); - winState->addTransition(spaceTransition); - - //We lost we should reach the final state - lostState->addTransition(lostState, SIGNAL(finished()), final); - - machine->start(); -} - -LevelState::LevelState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game) -{ -} -void LevelState::onEntry(QEvent *) -{ - initializeLevel(); -} - -void LevelState::initializeLevel() -{ - //we re-init the boat - scene->boat->setPos(scene->width()/2, scene->sealLevel() - scene->boat->size().height()); - scene->boat->setCurrentSpeed(0); - scene->boat->setCurrentDirection(Boat::None); - scene->boat->setBombsLaunched(0); - scene->boat->show(); - scene->setFocusItem(scene->boat,Qt::OtherFocusReason); - scene->boat->run(); - - scene->progressItem->setScore(game->score); - scene->progressItem->setLevel(game->currentLevel + 1); - - GraphicsScene::LevelDescription currentLevelDescription = scene->levelsData.value(game->currentLevel); - - for (int i = 0; i < currentLevelDescription.submarines.size(); ++i ) { - - QPair subContent = currentLevelDescription.submarines.at(i); - GraphicsScene::SubmarineDescription submarineDesc = scene->submarinesData.at(subContent.first); - - for (int j = 0; j < subContent.second; ++j ) { - SubMarine *sub = new SubMarine(submarineDesc.type, submarineDesc.name, submarineDesc.points); - scene->addItem(sub); - int random = (qrand() % 15 + 1); - qreal x = random == 13 || random == 5 ? 0 : scene->width() - sub->size().width(); - qreal y = scene->height() -(qrand() % 150 + 1) - sub->size().height(); - sub->setPos(x,y); - sub->setCurrentDirection(x == 0 ? SubMarine::Right : SubMarine::Left); - sub->setCurrentSpeed(qrand() % 3 + 1); - } - } -} - -/** Pause State */ -PauseState::PauseState(GraphicsScene *scene, QState *parent) : QState(parent),scene(scene) -{ -} -void PauseState::onEntry(QEvent *) -{ - AnimationManager::self()->pauseAll(); - scene->boat->setEnabled(false); -} -void PauseState::onExit(QEvent *) -{ - AnimationManager::self()->resumeAll(); - scene->boat->setEnabled(true); - scene->boat->setFocus(); -} - -/** Lost State */ -LostState::LostState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game) -{ -} - -void LostState::onEntry(QEvent *) -{ - //The message to display - QString message = QString("You lose on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score); - - //We set the level back to 0 - game->currentLevel = 0; - - //We set the score back to 0 - game->score = 0; - - //We clear the scene - scene->clearScene(); - - //we have only one view - QMessageBox::information(scene->views().at(0),"You lose",message); -} - -/** Win State */ -WinState::WinState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game) -{ -} - -void WinState::onEntry(QEvent *) -{ - //We clear the scene - scene->clearScene(); - - QString message; - if (scene->levelsData.size() - 1 != game->currentLevel) { - message = QString("You win the level %1. Your score is %2.\nPress Space to continue after closing this dialog.").arg(game->currentLevel+1).arg(game->score); - //We increment the level number - game->currentLevel++; - } else { - message = QString("You finish the game on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score); - //We set the level back to 0 - game->currentLevel = 0; - //We set the score back to 0 - game->score = 0; - } - - //we have only one view - QMessageBox::information(scene->views().at(0),"You win",message); -} - -/** UpdateScore State */ -UpdateScoreState::UpdateScoreState(PlayState *game, QState *parent) : QState(parent) -{ - this->game = game; -} -void UpdateScoreState::onEntry(QEvent *e) -{ - QState::onEntry(e); -} - -/** Win transition */ -UpdateScoreTransition::UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) - : QSignalTransition(scene,SIGNAL(subMarineDestroyed(int)), QList() << target), - game(game), scene(scene) -{ -} - -bool UpdateScoreTransition::eventTest(QEvent *event) -{ - if (!QSignalTransition::eventTest(event)) - return false; - else { - QSignalEvent *se = static_cast(event); - game->score += se->arguments().at(0).toInt(); - scene->progressItem->setScore(game->score); - return true; - } -} - -/** Win transition */ -WinTransition::WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) - : QSignalTransition(scene,SIGNAL(allSubMarineDestroyed(int)), QList() << target), - game(game), scene(scene) -{ -} - -bool WinTransition::eventTest(QEvent *event) -{ - if (!QSignalTransition::eventTest(event)) - return false; - else { - QSignalEvent *se = static_cast(event); - game->score += se->arguments().at(0).toInt(); - scene->progressItem->setScore(game->score); - return true; - } -} - -/** Space transition */ -CustomSpaceTransition::CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key) - : QKeyEventTransition(widget, type, key), - game(game) -{ -} - -bool CustomSpaceTransition::eventTest(QEvent *event) -{ - Q_UNUSED(event); - if (!QKeyEventTransition::eventTest(event)) - return false; - if (game->currentLevel != 0) - return true; - else - return false; - -} diff --git a/examples/animation/sub-attaq/states.h b/examples/animation/sub-attaq/states.h deleted file mode 100644 index 71375e0..0000000 --- a/examples/animation/sub-attaq/states.h +++ /dev/null @@ -1,180 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef STATES_H -#define STATES_H - -//Qt -#include -#include -#include -#include -#include - -class GraphicsScene; -class Boat; -class SubMarine; -QT_BEGIN_NAMESPACE -class QStateMachine; -QT_END_NAMESPACE - -class PlayState : public QState -{ -public: - PlayState(GraphicsScene *scene, QState *parent = 0); - ~PlayState(); - - protected: - void onEntry(QEvent *); - -private : - GraphicsScene *scene; - QStateMachine *machine; - int currentLevel; - int score; - QState *parallelChild; - - friend class UpdateScoreState; - friend class UpdateScoreTransition; - friend class WinTransition; - friend class CustomSpaceTransition; - friend class WinState; - friend class LostState; - friend class LevelState; -}; - -class LevelState : public QState -{ -public: - LevelState(GraphicsScene *scene, PlayState *game, QState *parent = 0); -protected: - void onEntry(QEvent *); -private : - void initializeLevel(); - GraphicsScene *scene; - PlayState *game; -}; - -class PauseState : public QState -{ -public: - PauseState(GraphicsScene *scene, QState *parent = 0); - -protected: - void onEntry(QEvent *); - void onExit(QEvent *); -private : - GraphicsScene *scene; - Boat *boat; -}; - -class LostState : public QState -{ -public: - LostState(GraphicsScene *scene, PlayState *game, QState *parent = 0); - -protected: - void onEntry(QEvent *); -private : - GraphicsScene *scene; - PlayState *game; -}; - -class WinState : public QState -{ -public: - WinState(GraphicsScene *scene, PlayState *game, QState *parent = 0); - -protected: - void onEntry(QEvent *); -private : - GraphicsScene *scene; - PlayState *game; -}; - -class UpdateScoreState : public QState -{ -public: - UpdateScoreState(PlayState *game, QState *parent); -protected: - void onEntry(QEvent *); -private: - QPropertyAnimation *scoreAnimation; - PlayState *game; -}; - -//These transtion is used to update the score -class UpdateScoreTransition : public QSignalTransition -{ -public: - UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target); -protected: - virtual bool eventTest(QEvent *event); -private: - PlayState * game; - GraphicsScene *scene; -}; - -//These transtion test if we have won the game -class WinTransition : public QSignalTransition -{ -public: - WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target); -protected: - virtual bool eventTest(QEvent *event); -private: - PlayState * game; - GraphicsScene *scene; -}; - -//These transtion is true if one level has been completed and the player want to continue - class CustomSpaceTransition : public QKeyEventTransition -{ -public: - CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key); -protected: - virtual bool eventTest(QEvent *event); -private: - PlayState *game; - int key; -}; - -#endif // STATES_H diff --git a/examples/animation/sub-attaq/sub-attaq.pro b/examples/animation/sub-attaq/sub-attaq.pro deleted file mode 100644 index d13a099..0000000 --- a/examples/animation/sub-attaq/sub-attaq.pro +++ /dev/null @@ -1,36 +0,0 @@ -contains(QT_CONFIG, opengl):QT += opengl - -HEADERS += boat.h \ - bomb.h \ - mainwindow.h \ - submarine.h \ - torpedo.h \ - pixmapitem.h \ - graphicsscene.h \ - animationmanager.h \ - states.h \ - boat_p.h \ - submarine_p.h \ - custompropertyanimation.h \ - qanimationstate.h \ - progressitem.h -SOURCES += boat.cpp \ - bomb.cpp \ - main.cpp \ - mainwindow.cpp \ - submarine.cpp \ - torpedo.cpp \ - pixmapitem.cpp \ - graphicsscene.cpp \ - animationmanager.cpp \ - states.cpp \ - custompropertyanimation.cpp \ - qanimationstate.cpp \ - progressitem.cpp -RESOURCES += subattaq.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/animation/sub-attaq -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS sub-attaq.pro pics -sources.path = $$[QT_INSTALL_EXAMPLES]/animation/sub-attaq -INSTALLS += target sources diff --git a/examples/animation/sub-attaq/subattaq.qrc b/examples/animation/sub-attaq/subattaq.qrc deleted file mode 100644 index c76f8ef..0000000 --- a/examples/animation/sub-attaq/subattaq.qrc +++ /dev/null @@ -1,38 +0,0 @@ - - - pics/scalable/sub-attaq.svg - pics/scalable/submarine.svg - pics/scalable/boat.svg - pics/scalable/torpedo.svg - pics/welcome/logo-s.png - pics/welcome/logo-u.png - pics/welcome/logo-b.png - pics/welcome/logo-dash.png - pics/welcome/logo-a.png - pics/welcome/logo-t.png - pics/welcome/logo-t2.png - pics/welcome/logo-a2.png - pics/welcome/logo-q.png - pics/welcome/logo-excl.png - pics/big/background.png - pics/big/boat.png - pics/big/bomb.png - pics/big/submarine.png - pics/big/surface.png - pics/big/torpedo.png - pics/small/background.png - pics/small/boat.png - pics/small/bomb.png - pics/small/submarine.png - pics/small/surface.png - pics/small/torpedo.png - pics/big/explosion/boat/step1.png - pics/big/explosion/boat/step2.png - pics/big/explosion/boat/step3.png - pics/big/explosion/boat/step4.png - pics/big/explosion/submarine/step1.png - pics/big/explosion/submarine/step2.png - pics/big/explosion/submarine/step3.png - pics/big/explosion/submarine/step4.png - - diff --git a/examples/animation/sub-attaq/submarine.cpp b/examples/animation/sub-attaq/submarine.cpp deleted file mode 100644 index d8cf1da..0000000 --- a/examples/animation/sub-attaq/submarine.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//Own -#include "submarine.h" -#include "submarine_p.h" -#include "torpedo.h" -#include "pixmapitem.h" -#include "graphicsscene.h" -#include "animationmanager.h" -#include "custompropertyanimation.h" -#include "qanimationstate.h" - -#include -#include -#include -#include - -static QAbstractAnimation *setupDestroyAnimation(SubMarine *sub) -{ - QSequentialAnimationGroup *group = new QSequentialAnimationGroup(sub); -#if QT_VERSION >=0x040500 - PixmapItem *step1 = new PixmapItem(QString("explosion/submarine/step1"),GraphicsScene::Big, sub); - step1->setZValue(6); - PixmapItem *step2 = new PixmapItem(QString("explosion/submarine/step2"),GraphicsScene::Big, sub); - step2->setZValue(6); - PixmapItem *step3 = new PixmapItem(QString("explosion/submarine/step3"),GraphicsScene::Big, sub); - step3->setZValue(6); - PixmapItem *step4 = new PixmapItem(QString("explosion/submarine/step4"),GraphicsScene::Big, sub); - step4->setZValue(6); - step1->setOpacity(0); - step2->setOpacity(0); - step3->setOpacity(0); - step4->setOpacity(0); - CustomPropertyAnimation *anim1 = new CustomPropertyAnimation(sub); - anim1->setMemberFunctions((QGraphicsItem*)step1, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim1->setDuration(100); - anim1->setEndValue(1); - CustomPropertyAnimation *anim2 = new CustomPropertyAnimation(sub); - anim2->setMemberFunctions((QGraphicsItem*)step2, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim2->setDuration(100); - anim2->setEndValue(1); - CustomPropertyAnimation *anim3 = new CustomPropertyAnimation(sub); - anim3->setMemberFunctions((QGraphicsItem*)step3, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim3->setDuration(100); - anim3->setEndValue(1); - CustomPropertyAnimation *anim4 = new CustomPropertyAnimation(sub); - anim4->setMemberFunctions((QGraphicsItem*)step4, &QGraphicsItem::opacity, &QGraphicsItem::setOpacity); - anim4->setDuration(100); - anim4->setEndValue(1); - group->addAnimation(anim1); - group->addAnimation(anim2); - group->addAnimation(anim3); - group->addAnimation(anim4); -#else - // work around for a bug where we don't transition if the duration is zero. - QtPauseAnimation *anim = new QtPauseAnimation(group); - anim->setDuration(1); - group->addAnimation(anim); -#endif - AnimationManager::self()->registerAnimation(group); - return group; -} - - -SubMarine::SubMarine(int type, const QString &name, int points, QGraphicsItem * parent, Qt::WindowFlags wFlags) - : QGraphicsWidget(parent,wFlags), subType(type), subName(name), subPoints(points), speed(0), direction(SubMarine::None) -{ - pixmapItem = new PixmapItem(QString("submarine"),GraphicsScene::Big, this); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setZValue(5); - setFlags(QGraphicsItem::ItemIsMovable); - resize(pixmapItem->boundingRect().width(),pixmapItem->boundingRect().height()); - setTransformOrigin(boundingRect().center()); - - //We setup the state machine of the submarine - QStateMachine *machine = new QStateMachine(this); - - //This state is when the boat is moving/rotating - QState *moving = new QState(machine->rootState()); - - //This state is when the boat is moving from left to right - MovementState *movement = new MovementState(this, moving); - - //This state is when the boat is moving from left to right - ReturnState *rotation = new ReturnState(this, moving); - - //This is the initial state of the moving root state - moving->setInitialState(movement); - - movement->addTransition(this, SIGNAL(subMarineStateChanged()), moving); - - //This is the initial state of the machine - machine->setInitialState(moving); - - //End - QFinalState *final = new QFinalState(machine->rootState()); - - //If the moving animation is finished we move to the return state - movement->addTransition(movement, SIGNAL(animationFinished()), rotation); - - //If the return animation is finished we move to the moving state - rotation->addTransition(rotation, SIGNAL(animationFinished()), movement); - - //This state play the destroyed animation - QAnimationState *destroyedState = new QAnimationState(machine->rootState()); - destroyedState->setAnimation(setupDestroyAnimation(this)); - - //Play a nice animation when the submarine is destroyed - moving->addTransition(this, SIGNAL(subMarineDestroyed()), destroyedState); - - //Transition to final state when the destroyed animation is finished - destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final); - - //The machine has finished to be executed, then the submarine is dead - connect(machine,SIGNAL(finished()),this, SIGNAL(subMarineExecutionFinished())); - - machine->start(); -} - -int SubMarine::points() -{ - return subPoints; -} - -void SubMarine::setCurrentDirection(SubMarine::Movement direction) -{ - if (this->direction == direction) - return; - if (direction == SubMarine::Right && this->direction == SubMarine::None) { - setYRotation(180); - } - this->direction = direction; -} - -enum SubMarine::Movement SubMarine::currentDirection() const -{ - return direction; -} - -void SubMarine::setCurrentSpeed(int speed) -{ - if (speed < 0 || speed > 3) { - qWarning("SubMarine::setCurrentSpeed : The speed is invalid"); - } - this->speed = speed; - emit subMarineStateChanged(); -} - -int SubMarine::currentSpeed() const -{ - return speed; -} - -void SubMarine::launchTorpedo(int speed) -{ - Torpedo * torp = new Torpedo(); - GraphicsScene *scene = static_cast(this->scene()); - scene->addItem(torp); - torp->setPos(x(), y()); - torp->setCurrentSpeed(speed); - torp->launch(); -} - -void SubMarine::destroy() -{ - emit subMarineDestroyed(); -} - -int SubMarine::type() const -{ - return Type; -} diff --git a/examples/animation/sub-attaq/submarine.h b/examples/animation/sub-attaq/submarine.h deleted file mode 100644 index 4001603..0000000 --- a/examples/animation/sub-attaq/submarine.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __SUBMARINE__H__ -#define __SUBMARINE__H__ - -//Qt -#include -#include - -class PixmapItem; - -class Torpedo; - -class SubMarine : public QGraphicsWidget -{ -Q_OBJECT -public: - enum Movement { - None = 0, - Left, - Right - }; - enum { Type = UserType + 1 }; - SubMarine(int type, const QString &name, int points, QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); - - int points(); - - void setCurrentDirection(Movement direction); - enum Movement currentDirection() const; - - void setCurrentSpeed(int speed); - int currentSpeed() const; - - void launchTorpedo(int speed); - void destroy(); - - virtual int type() const; - -Q_SIGNALS: - void subMarineDestroyed(); - void subMarineExecutionFinished(); - void subMarineStateChanged(); - -private: - int subType; - QString subName; - int subPoints; - int speed; - Movement direction; - PixmapItem *pixmapItem; -}; - -#endif //__SUBMARINE__H__ diff --git a/examples/animation/sub-attaq/submarine_p.h b/examples/animation/sub-attaq/submarine_p.h deleted file mode 100644 index 8c31eb7..0000000 --- a/examples/animation/sub-attaq/submarine_p.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SUBMARINE_P_H -#define SUBMARINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -//Own -#include "animationmanager.h" -#include "submarine.h" -#include "qanimationstate.h" - -//Qt -#include -#include - -//This state is describing when the boat is moving right -class MovementState : public QAnimationState -{ -Q_OBJECT -public: - MovementState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent) - { - movementAnimation = new QPropertyAnimation(submarine, "pos"); - connect(movementAnimation,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationMovementValueChanged(const QVariant &))); - setAnimation(movementAnimation); - AnimationManager::self()->registerAnimation(movementAnimation); - this->submarine = submarine; - } - -protected slots: - void onAnimationMovementValueChanged(const QVariant &) - { - if (qrand() % 200 + 1 == 3) - submarine->launchTorpedo(qrand() % 3 + 1); - } - -protected: - void onEntry(QEvent *e) - { - if (submarine->currentDirection() == SubMarine::Left) { - movementAnimation->setEndValue(QPointF(0,submarine->y())); - movementAnimation->setDuration(submarine->x()/submarine->currentSpeed()*12); - } - else /*if (submarine->currentDirection() == SubMarine::Right)*/ { - movementAnimation->setEndValue(QPointF(submarine->scene()->width()-submarine->size().width(),submarine->y())); - movementAnimation->setDuration((submarine->scene()->width()-submarine->size().width()-submarine->x())/submarine->currentSpeed()*12); - } - movementAnimation->setStartValue(submarine->pos()); - QAnimationState::onEntry(e); - } - -private: - SubMarine *submarine; - QPropertyAnimation *movementAnimation; -}; - -//This state is describing when the boat is moving right -class ReturnState : public QAnimationState -{ -public: - ReturnState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent) - { - returnAnimation = new QPropertyAnimation(submarine, "yRotation"); - AnimationManager::self()->registerAnimation(returnAnimation); - setAnimation(returnAnimation); - this->submarine = submarine; - } - -protected: - void onEntry(QEvent *e) - { - returnAnimation->stop(); - returnAnimation->setStartValue(submarine->yRotation()); - returnAnimation->setEndValue(submarine->currentDirection() == SubMarine::Right ? 360. : 180.); - returnAnimation->setDuration(500); - QAnimationState::onEntry(e); - } - - void onExit(QEvent *e) - { - submarine->currentDirection() == SubMarine::Right ? submarine->setCurrentDirection(SubMarine::Left) : submarine->setCurrentDirection(SubMarine::Right); - QAnimationState::onExit(e); - } - -private: - SubMarine *submarine; - QPropertyAnimation *returnAnimation; -}; - -#endif // SUBMARINE_P_H diff --git a/examples/animation/sub-attaq/torpedo.cpp b/examples/animation/sub-attaq/torpedo.cpp deleted file mode 100644 index 02a54fc..0000000 --- a/examples/animation/sub-attaq/torpedo.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//Own -#include "torpedo.h" -#include "pixmapitem.h" -#include "boat.h" -#include "graphicsscene.h" -#include "animationmanager.h" -#include "qanimationstate.h" - -#include -#include -#include - -Torpedo::Torpedo(QGraphicsItem * parent, Qt::WindowFlags wFlags) - : QGraphicsWidget(parent,wFlags), currentSpeed(0), launchAnimation(0) -{ - pixmapItem = new PixmapItem(QString::fromLatin1("torpedo"),GraphicsScene::Big, this); - setZValue(2); - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setFlags(QGraphicsItem::ItemIsMovable); - resize(pixmapItem->boundingRect().size()); -} - -void Torpedo::launch() -{ - launchAnimation = new QPropertyAnimation(this, "pos"); - AnimationManager::self()->registerAnimation(launchAnimation); - launchAnimation->setEndValue(QPointF(x(),qobject_cast(scene())->sealLevel() - 15)); - launchAnimation->setEasingCurve(QEasingCurve::InQuad); - launchAnimation->setDuration(y()/currentSpeed*10); - connect(launchAnimation,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationLaunchValueChanged(const QVariant &))); - - //We setup the state machine of the torpedo - QStateMachine *machine = new QStateMachine(this); - - //This state is when the launch animation is playing - QAnimationState *launched = new QAnimationState(machine->rootState()); - launched->setAnimation(launchAnimation); - - //End - QFinalState *final = new QFinalState(machine->rootState()); - - machine->setInitialState(launched); - - //### Add a nice animation when the torpedo is destroyed - launched->addTransition(this, SIGNAL(torpedoExplosed()),final); - - //If the animation is finished, then we move to the final state - launched->addTransition(launched, SIGNAL(animationFinished()), final); - - //The machine has finished to be executed, then the boat is dead - connect(machine,SIGNAL(finished()),this, SIGNAL(torpedoExecutionFinished())); - - machine->start(); -} - -void Torpedo::setCurrentSpeed(int speed) -{ - if (speed < 0) { - qWarning("Torpedo::setCurrentSpeed : The speed is invalid"); - return; - } - currentSpeed = speed; -} - -void Torpedo::onAnimationLaunchValueChanged(const QVariant &) -{ - foreach (QGraphicsItem *item , collidingItems(Qt::IntersectsItemBoundingRect)) { - if (item->type() == Boat::Type) { - Boat *b = static_cast(item); - b->destroy(); - } - } -} - -void Torpedo::destroy() -{ - launchAnimation->stop(); - emit torpedoExplosed(); -} diff --git a/examples/animation/sub-attaq/torpedo.h b/examples/animation/sub-attaq/torpedo.h deleted file mode 100644 index 4a0f457..0000000 --- a/examples/animation/sub-attaq/torpedo.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef __TORPEDO__H__ -#define __TORPEDO__H__ - -//Qt -#include - -#include -#include - -class PixmapItem; - -class Torpedo : public QGraphicsWidget -{ -Q_OBJECT -Q_PROPERTY(QPointF pos READ pos WRITE setPos) -public: - Torpedo(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); - void launch(); - void setCurrentSpeed(int speed); - void destroy(); - -Q_SIGNALS: - void torpedoExplosed(); - void torpedoExecutionFinished(); - -private slots: - void onAnimationLaunchValueChanged(const QVariant &); - -private: - int currentSpeed; - PixmapItem *pixmapItem; - QVariantAnimation *launchAnimation; -}; - -#endif //__TORPEDO__H__ diff --git a/examples/examples.pro b/examples/examples.pro index bfcf9b4..41501a0 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -1,6 +1,5 @@ TEMPLATE = subdirs SUBDIRS = \ - animation \ desktop \ dialogs \ draganddrop \ @@ -15,7 +14,6 @@ SUBDIRS = \ qtconcurrent \ richtext \ sql \ - statemachine \ threads \ tools \ tutorials \ diff --git a/examples/statemachine/README b/examples/statemachine/README deleted file mode 100644 index 2879e67..0000000 --- a/examples/statemachine/README +++ /dev/null @@ -1,36 +0,0 @@ -Qt is provided with a powerful hierchical finite state machine through -the Qt State Machine classes. - -The example launcher provided with Qt can be used to explore each of the -examples in this directory. - -Documentation for these examples can be found via the Tutorial and Examples -link in the main Qt documentation. - - -Finding the Qt Examples and Demos launcher -========================================== - -On Windows: - -The launcher can be accessed via the Windows Start menu. Select the menu -entry entitled "Qt Examples and Demos" entry in the submenu containing -the Qt tools. - -On Mac OS X: - -For the binary distribution, the qtdemo executable is installed in the -/Developer/Applications/Qt directory. For the source distribution, it is -installed alongside the other Qt tools on the path specified when Qt is -configured. - -On Unix/Linux: - -The qtdemo executable is installed alongside the other Qt tools on the path -specified when Qt is configured. - -On all platforms: - -The source code for the launcher can be found in the demos/qtdemo directory -in the Qt package. This example is built at the same time as the Qt libraries, -tools, examples, and demonstrations. diff --git a/examples/statemachine/eventtransitions/eventtransitions.pro b/examples/statemachine/eventtransitions/eventtransitions.pro deleted file mode 100644 index 7e92cf2..0000000 --- a/examples/statemachine/eventtransitions/eventtransitions.pro +++ /dev/null @@ -1,7 +0,0 @@ -SOURCES = main.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/eventtransitions -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS eventtransitions.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/eventtransitions -INSTALLS += target sources diff --git a/examples/statemachine/eventtransitions/main.cpp b/examples/statemachine/eventtransitions/main.cpp deleted file mode 100644 index aba0c73..0000000 --- a/examples/statemachine/eventtransitions/main.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#ifdef QT_STATEMACHINE_SOLUTION -#include -#include -#include -#endif - -//! [0] -class Window : public QWidget -{ -public: - Window(QWidget *parent = 0) - : QWidget(parent) - { - QPushButton *button = new QPushButton(this); - button->setGeometry(QRect(100, 100, 100, 100)); -//! [0] - -//! [1] - QStateMachine *machine = new QStateMachine(this); - - QState *s1 = new QState(); - s1->assignProperty(button, "text", "Outside"); - - QState *s2 = new QState(); - s2->assignProperty(button, "text", "Inside"); -//! [1] - -//! [2] - QEventTransition *enterTransition = new QEventTransition(button, QEvent::Enter); - enterTransition->setTargetState(s2); - s1->addTransition(enterTransition); -//! [2] - -//! [3] - QEventTransition *leaveTransition = new QEventTransition(button, QEvent::Leave); - leaveTransition->setTargetState(s1); - s2->addTransition(leaveTransition); -//! [3] - -//! [4] - QState *s3 = new QState(); - s3->assignProperty(button, "text", "Pressing..."); - - QEventTransition *pressTransition = new QEventTransition(button, QEvent::MouseButtonPress); - pressTransition->setTargetState(s3); - s2->addTransition(pressTransition); - - QEventTransition *releaseTransition = new QEventTransition(button, QEvent::MouseButtonRelease); - releaseTransition->setTargetState(s2); - s3->addTransition(releaseTransition); -//! [4] - -//! [5] - machine->addState(s1); - machine->addState(s2); - machine->addState(s3); - - machine->setInitialState(s1); - machine->start(); - } -}; -//! [5] - -//! [6] -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - Window window; - window.resize(300, 300); - window.show(); - - return app.exec(); -} -//! [6] diff --git a/examples/statemachine/factorial/factorial.pro b/examples/statemachine/factorial/factorial.pro deleted file mode 100644 index 14a6833..0000000 --- a/examples/statemachine/factorial/factorial.pro +++ /dev/null @@ -1,11 +0,0 @@ -QT = core -win32: CONFIG += console -mac:CONFIG -= app_bundle - -SOURCES += main.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/factorial -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS factorial.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/factorial -INSTALLS += target sources diff --git a/examples/statemachine/factorial/main.cpp b/examples/statemachine/factorial/main.cpp deleted file mode 100644 index 1065eb8..0000000 --- a/examples/statemachine/factorial/main.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#ifdef QT_STATEMACHINE_SOLUTION -#include -#include -#include -#include -#endif - -//! [0] -class Factorial : public QObject -{ - Q_OBJECT - Q_PROPERTY(int x READ x WRITE setX) - Q_PROPERTY(int fac READ fac WRITE setFac) -public: - Factorial(QObject *parent = 0) - : QObject(parent), m_x(-1), m_fac(1) - { - } - - int x() const - { - return m_x; - } - - void setX(int x) - { - if (x == m_x) - return; - m_x = x; - emit xChanged(x); - } - - int fac() const - { - return m_fac; - } - - void setFac(int fac) - { - m_fac = fac; - } - -Q_SIGNALS: - void xChanged(int value); - -private: - int m_x; - int m_fac; -}; -//! [0] - -//! [1] -class FactorialLoopTransition : public QSignalTransition -{ -public: - FactorialLoopTransition(Factorial *fact) - : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact) - {} - - virtual bool eventTest(QEvent *e) - { - if (!QSignalTransition::eventTest(e)) - return false; - QSignalEvent *se = static_cast(e); - return se->arguments().at(0).toInt() > 1; - } - - virtual void onTransition(QEvent *e) - { - QSignalEvent *se = static_cast(e); - int x = se->arguments().at(0).toInt(); - int fac = m_fact->property("fac").toInt(); - m_fact->setProperty("fac", x * fac); - m_fact->setProperty("x", x - 1); - } - -private: - Factorial *m_fact; -}; -//! [1] - -//! [2] -class FactorialDoneTransition : public QSignalTransition -{ -public: - FactorialDoneTransition(Factorial *fact) - : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact) - {} - - virtual bool eventTest(QEvent *e) - { - if (!QSignalTransition::eventTest(e)) - return false; - QSignalEvent *se = static_cast(e); - return se->arguments().at(0).toInt() <= 1; - } - - virtual void onTransition(QEvent *) - { - fprintf(stdout, "%d\n", m_fact->property("fac").toInt()); - } - -private: - Factorial *m_fact; -}; -//! [2] - -//! [3] -int main(int argc, char **argv) -{ - QCoreApplication app(argc, argv); - Factorial factorial; - QStateMachine machine; -//! [3] - -//! [4] - QState *compute = new QState(machine.rootState()); - compute->assignProperty(&factorial, "fac", 1); - compute->assignProperty(&factorial, "x", 6); - compute->addTransition(new FactorialLoopTransition(&factorial)); -//! [4] - -//! [5] - QFinalState *done = new QFinalState(machine.rootState()); - FactorialDoneTransition *doneTransition = new FactorialDoneTransition(&factorial); - doneTransition->setTargetState(done); - compute->addTransition(doneTransition); -//! [5] - -//! [6] - machine.setInitialState(compute); - QObject::connect(&machine, SIGNAL(finished()), &app, SLOT(quit())); - machine.start(); - - return app.exec(); -} -//! [6] - -#include "main.moc" diff --git a/examples/statemachine/pingpong/main.cpp b/examples/statemachine/pingpong/main.cpp deleted file mode 100644 index 331627e..0000000 --- a/examples/statemachine/pingpong/main.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#ifdef QT_STATEMACHINE_SOLUTION -#include -#include -#include -#endif - -//! [0] -class PingEvent : public QEvent -{ -public: - PingEvent() : QEvent(QEvent::Type(QEvent::User+2)) - {} -}; - -class PongEvent : public QEvent -{ -public: - PongEvent() : QEvent(QEvent::Type(QEvent::User+3)) - {} -}; -//! [0] - -//! [1] -class Pinger : public QState -{ -public: - Pinger(QState *parent) - : QState(parent) {} - -protected: - virtual void onEntry(QEvent *) - { - machine()->postEvent(new PingEvent()); - fprintf(stdout, "ping?\n"); - } -}; -//! [1] - -//! [3] -class PongTransition : public QAbstractTransition -{ -public: - PongTransition() {} - -protected: - virtual bool eventTest(QEvent *e) { - return (e->type() == QEvent::User+3); - } - virtual void onTransition(QEvent *) - { - machine()->postEvent(new PingEvent(), 500); - fprintf(stdout, "ping?\n"); - } -}; -//! [3] - -//! [2] -class PingTransition : public QAbstractTransition -{ -public: - PingTransition() {} - -protected: - virtual bool eventTest(QEvent *e) { - return (e->type() == QEvent::User+2); - } - virtual void onTransition(QEvent *) - { - machine()->postEvent(new PongEvent(), 500); - fprintf(stdout, "pong!\n"); - } -}; -//! [2] - -//! [4] -int main(int argc, char **argv) -{ - QCoreApplication app(argc, argv); - - QStateMachine machine; - QState *group = new QState(QState::ParallelStates); - group->setObjectName("group"); -//! [4] - -//! [5] - Pinger *pinger = new Pinger(group); - pinger->setObjectName("pinger"); - pinger->addTransition(new PongTransition()); - - QState *ponger = new QState(group); - ponger->setObjectName("ponger"); - ponger->addTransition(new PingTransition()); -//! [5] - -//! [6] - machine.addState(group); - machine.setInitialState(group); - machine.start(); - - return app.exec(); -} -//! [6] diff --git a/examples/statemachine/pingpong/pingpong.pro b/examples/statemachine/pingpong/pingpong.pro deleted file mode 100644 index 42eab6c..0000000 --- a/examples/statemachine/pingpong/pingpong.pro +++ /dev/null @@ -1,11 +0,0 @@ -QT = core -win32: CONFIG += console -mac:CONFIG -= app_bundle - -SOURCES = main.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/pingpong -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS pingpong.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/pingpong -INSTALLS += target sources diff --git a/examples/statemachine/statemachine.pro b/examples/statemachine/statemachine.pro deleted file mode 100644 index 5074a3c..0000000 --- a/examples/statemachine/statemachine.pro +++ /dev/null @@ -1,15 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS = \ - eventtransitions \ - factorial \ - pingpong \ - trafficlight \ - twowaybutton \ - tankgame \ - tankgameplugins - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS statemachine.pro README -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine -INSTALLS += target sources diff --git a/examples/statemachine/tankgame/gameitem.cpp b/examples/statemachine/tankgame/gameitem.cpp deleted file mode 100644 index ad8b37c..0000000 --- a/examples/statemachine/tankgame/gameitem.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "gameitem.h" - -#include -#include - -GameItem::GameItem(QObject *parent) : QObject(parent) -{ -} - -QPointF GameItem::tryMove(const QPointF &requestedPosition, QLineF *collidedLine, - QGraphicsItem **collidedItem) const -{ - QLineF movementPath(pos(), requestedPosition); - - qreal cannonLength = 0.0; - { - QPointF p1 = boundingRect().center(); - QPointF p2 = QPointF(boundingRect().right() + 10.0, p1.y()); - - cannonLength = QLineF(mapToScene(p1), mapToScene(p2)).length(); - } - - movementPath.setLength(movementPath.length() + cannonLength); - - QRectF boundingRectPath(QPointF(qMin(movementPath.x1(), movementPath.x2()), qMin(movementPath.y1(), movementPath.y2())), - QPointF(qMax(movementPath.x1(), movementPath.x2()), qMax(movementPath.y1(), movementPath.y2()))); - - QList itemsInRect = scene()->items(boundingRectPath, Qt::IntersectsItemBoundingRect); - - QPointF nextPoint = requestedPosition; - QRectF sceneRect = scene()->sceneRect(); - - foreach (QGraphicsItem *item, itemsInRect) { - if (item == static_cast(this)) - continue; - - QPolygonF mappedBoundingRect = item->mapToScene(item->boundingRect()); - for (int i=0; isceneRect().topLeft(), scene()->sceneRect().bottomLeft()); - } - - if (nextPoint.x() > sceneRect.right()) { - nextPoint.rx() = sceneRect.right(); - if (collidedLine != 0) - *collidedLine = QLineF(scene()->sceneRect().topRight(), scene()->sceneRect().bottomRight()); - } - - if (nextPoint.y() < sceneRect.top()) { - nextPoint.ry() = sceneRect.top(); - if (collidedLine != 0) - *collidedLine = QLineF(scene()->sceneRect().topLeft(), scene()->sceneRect().topRight()); - } - - if (nextPoint.y() > sceneRect.bottom()) { - nextPoint.ry() = sceneRect.bottom(); - if (collidedLine != 0) - *collidedLine = QLineF(scene()->sceneRect().bottomLeft(), scene()->sceneRect().bottomRight()); - } - - return nextPoint; -} - diff --git a/examples/statemachine/tankgame/gameitem.h b/examples/statemachine/tankgame/gameitem.h deleted file mode 100644 index 90b0a6c..0000000 --- a/examples/statemachine/tankgame/gameitem.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GAMEITEM_H -#define GAMEITEM_H - -#include - -QT_BEGIN_NAMESPACE -class QLineF; -QT_END_NAMESPACE -class GameItem: public QObject, public QGraphicsItem -{ - Q_OBJECT -public: - enum { Type = UserType + 1 }; - int type() const { return Type; } - - GameItem(QObject *parent = 0); - - virtual void idle(qreal elapsed) = 0; - -protected: - QPointF tryMove(const QPointF &requestedPosition, QLineF *collidedLine = 0, - QGraphicsItem **collidedItem = 0) const; -}; - -#endif diff --git a/examples/statemachine/tankgame/gameovertransition.cpp b/examples/statemachine/tankgame/gameovertransition.cpp deleted file mode 100644 index 360e902..0000000 --- a/examples/statemachine/tankgame/gameovertransition.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "gameovertransition.h" -#include "tankitem.h" - -#include -#include - -GameOverTransition::GameOverTransition(QAbstractState *targetState) - : QSignalTransition(new QSignalMapper(), SIGNAL(mapped(QObject*))) -{ - setTargetState(targetState); - - QSignalMapper *mapper = qobject_cast(senderObject()); - mapper->setParent(this); -} - -void GameOverTransition::addTankItem(TankItem *tankItem) -{ - m_tankItems.append(tankItem); - - QSignalMapper *mapper = qobject_cast(senderObject()); - mapper->setMapping(tankItem, tankItem); - connect(tankItem, SIGNAL(aboutToBeDestroyed()), mapper, SLOT(map())); -} - -bool GameOverTransition::eventTest(QEvent *e) -{ - bool ret = QSignalTransition::eventTest(e); - - if (ret) { - QSignalEvent *signalEvent = static_cast(e); - QObject *sender = qvariant_cast(signalEvent->arguments().at(0)); - TankItem *tankItem = qobject_cast(sender); - m_tankItems.removeAll(tankItem); - - return m_tankItems.size() <= 1; - } else { - return false; - } -} diff --git a/examples/statemachine/tankgame/gameovertransition.h b/examples/statemachine/tankgame/gameovertransition.h deleted file mode 100644 index 5e99a75..0000000 --- a/examples/statemachine/tankgame/gameovertransition.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GAMEOVERTRANSITION_H -#define GAMEOVERTRANSITION_H - -#include - -class TankItem; -class GameOverTransition: public QSignalTransition -{ - Q_OBJECT -public: - GameOverTransition(QAbstractState *targetState); - - void addTankItem(TankItem *tankItem); - -protected: - bool eventTest(QEvent *event); - -private: - QList m_tankItems; -}; - -#endif diff --git a/examples/statemachine/tankgame/main.cpp b/examples/statemachine/tankgame/main.cpp deleted file mode 100644 index 185ad68..0000000 --- a/examples/statemachine/tankgame/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "mainwindow.h" - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - MainWindow mainWindow; - mainWindow.show(); - - return app.exec(); -} diff --git a/examples/statemachine/tankgame/mainwindow.cpp b/examples/statemachine/tankgame/mainwindow.cpp deleted file mode 100644 index 46e0db3..0000000 --- a/examples/statemachine/tankgame/mainwindow.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mainwindow.h" -#include "tankitem.h" -#include "rocketitem.h" -#include "plugin.h" -#include "gameovertransition.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent), m_scene(0), m_machine(0), m_runningState(0), m_started(false) -{ - init(); -} - -MainWindow::~MainWindow() -{ -} - -void MainWindow::addWall(const QRectF &wall) -{ - QGraphicsRectItem *item = new QGraphicsRectItem; - item->setRect(wall); - item->setBrush(Qt::darkGreen); - item->setPen(QPen(Qt::black, 0)); - - m_scene->addItem(item); -} - -void MainWindow::init() -{ - setWindowTitle("Pluggable Tank Game"); - - QGraphicsView *view = new QGraphicsView(this); - view->setRenderHints(QPainter::Antialiasing); - setCentralWidget(view); - - m_scene = new QGraphicsScene(this); - view->setScene(m_scene); - - QRectF sceneRect = QRectF(-200.0, -200.0, 400.0, 400.0); - m_scene->setSceneRect(sceneRect); - - { - TankItem *item = new TankItem(this); - - item->setPos(m_scene->sceneRect().topLeft() + QPointF(30.0, 30.0)); - item->setDirection(45.0); - item->setColor(Qt::red); - - m_spawns.append(item); - } - - { - TankItem *item = new TankItem(this); - - item->setPos(m_scene->sceneRect().topRight() + QPointF(-30.0, 30.0)); - item->setDirection(135.0); - item->setColor(Qt::green); - - m_spawns.append(item); - } - - { - TankItem *item = new TankItem(this); - - item->setPos(m_scene->sceneRect().bottomRight() + QPointF(-30.0, -30.0)); - item->setDirection(225.0); - item->setColor(Qt::blue); - - m_spawns.append(item); - } - - { - TankItem *item = new TankItem(this); - - item->setPos(m_scene->sceneRect().bottomLeft() + QPointF(30.0, -30.0)); - item->setDirection(315.0); - item->setColor(Qt::yellow); - - m_spawns.append(item); - } - - QPointF centerOfMap = sceneRect.center(); - - addWall(QRectF(centerOfMap + QPointF(-50.0, -60.0), centerOfMap + QPointF(50.0, -50.0))); - addWall(QRectF(centerOfMap - QPointF(-50.0, -60.0), centerOfMap - QPointF(50.0, -50.0))); - addWall(QRectF(centerOfMap + QPointF(-50.0, -50.0), centerOfMap + QPointF(-40.0, 50.0))); - addWall(QRectF(centerOfMap - QPointF(-50.0, -50.0), centerOfMap - QPointF(-40.0, 50.0))); - - addWall(QRectF(sceneRect.topLeft() + QPointF(sceneRect.width() / 2.0 - 5.0, -10.0), - sceneRect.topLeft() + QPointF(sceneRect.width() / 2.0 + 5.0, 100.0))); - addWall(QRectF(sceneRect.bottomLeft() + QPointF(sceneRect.width() / 2.0 - 5.0, 10.0), - sceneRect.bottomLeft() + QPointF(sceneRect.width() / 2.0 + 5.0, -100.0))); - addWall(QRectF(sceneRect.topLeft() + QPointF(-10.0, sceneRect.height() / 2.0 - 5.0), - sceneRect.topLeft() + QPointF(100.0, sceneRect.height() / 2.0 + 5.0))); - addWall(QRectF(sceneRect.topRight() + QPointF(10.0, sceneRect.height() / 2.0 - 5.0), - sceneRect.topRight() + QPointF(-100.0, sceneRect.height() / 2.0 + 5.0))); - - - QAction *addTankAction = menuBar()->addAction("&Add tank"); - QAction *runGameAction = menuBar()->addAction("&Run game"); - runGameAction->setObjectName("runGameAction"); - QAction *stopGameAction = menuBar()->addAction("&Stop game"); - menuBar()->addSeparator(); - QAction *quitAction = menuBar()->addAction("&Quit"); - - connect(addTankAction, SIGNAL(triggered()), this, SLOT(addTank())); - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - - m_machine = new QStateMachine(this); - QState *stoppedState = new QState(m_machine->rootState()); - stoppedState->setObjectName("stoppedState"); - stoppedState->assignProperty(runGameAction, "enabled", true); - stoppedState->assignProperty(stopGameAction, "enabled", false); - stoppedState->assignProperty(this, "started", false); - m_machine->setInitialState(stoppedState); - -//! [5] - QState *spawnsAvailable = new QState(stoppedState); - spawnsAvailable->assignProperty(addTankAction, "enabled", true); - - QState *noSpawnsAvailable = new QState(stoppedState); - noSpawnsAvailable->assignProperty(addTankAction, "enabled", false); -//! [5] - spawnsAvailable->setObjectName("spawnsAvailable"); - noSpawnsAvailable->setObjectName("noSpawnsAvailable"); - - spawnsAvailable->addTransition(this, SIGNAL(mapFull()), noSpawnsAvailable); - -//! [3] - QHistoryState *hs = new QHistoryState(stoppedState); - hs->setDefaultState(spawnsAvailable); -//! [3] - hs->setObjectName("hs"); - - stoppedState->setInitialState(hs); - -//! [0] - m_runningState = new QState(QState::ParallelStates, m_machine->rootState()); -//! [0] - m_runningState->setObjectName("runningState"); - m_runningState->assignProperty(addTankAction, "enabled", false); - m_runningState->assignProperty(runGameAction, "enabled", false); - m_runningState->assignProperty(stopGameAction, "enabled", true); - - QState *gameOverState = new QState(m_machine->rootState()); - gameOverState->setObjectName("gameOverState"); - gameOverState->assignProperty(stopGameAction, "enabled", false); - connect(gameOverState, SIGNAL(entered()), this, SLOT(gameOver())); - - stoppedState->addTransition(runGameAction, SIGNAL(triggered()), m_runningState); - m_runningState->addTransition(stopGameAction, SIGNAL(triggered()), stoppedState); - - m_gameOverTransition = new GameOverTransition(gameOverState); - m_runningState->addTransition(m_gameOverTransition); - - QTimer *timer = new QTimer(this); - timer->setInterval(100); - connect(timer, SIGNAL(timeout()), this, SLOT(runStep())); - connect(m_runningState, SIGNAL(entered()), timer, SLOT(start())); - connect(m_runningState, SIGNAL(exited()), timer, SLOT(stop())); - - m_machine->start(); - m_time.start(); -} - -void MainWindow::runStep() -{ - if (!m_started) { - m_time.restart(); - m_started = true; - } else { - int elapsed = m_time.elapsed(); - if (elapsed > 0) { - m_time.restart(); - qreal elapsedSecs = elapsed / 1000.0; - QList items = m_scene->items(); - foreach (QGraphicsItem *item, items) { - if (GameItem *gameItem = qgraphicsitem_cast(item)) - gameItem->idle(elapsedSecs); - } - } - } -} - -void MainWindow::gameOver() -{ - QList items = m_scene->items(); - - TankItem *lastTankStanding = 0; - foreach (QGraphicsItem *item, items) { - if (GameItem *gameItem = qgraphicsitem_cast(item)) { - if ((lastTankStanding = qobject_cast(gameItem)) != 0) - break; - } - } - - QMessageBox::information(this, "Game over!", - QString::fromLatin1("The tank played by '%1' has won!").arg(lastTankStanding->objectName())); -} - -void MainWindow::addRocket() -{ - TankItem *tankItem = qobject_cast(sender()); - if (tankItem != 0) { - RocketItem *rocketItem = new RocketItem; - - QPointF s = tankItem->mapToScene(QPointF(tankItem->boundingRect().right() + 10.0, - tankItem->boundingRect().center().y())); - rocketItem->setPos(s); - rocketItem->setDirection(tankItem->direction()); - m_scene->addItem(rocketItem); - } -} - -void MainWindow::addTank() -{ - Q_ASSERT(!m_spawns.isEmpty()); - - QDir pluginsDir(qApp->applicationDirPath()); -#if defined(Q_OS_WIN) - if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release") - pluginsDir.cdUp(); -#elif defined(Q_OS_MAC) - if (pluginsDir.dirName() == "MacOS") { - pluginsDir.cdUp(); - pluginsDir.cdUp(); - pluginsDir.cdUp(); - } -#endif - - pluginsDir.cd("plugins"); - - QStringList itemNames; - QList items; - foreach (QString fileName, pluginsDir.entryList(QDir::Files)) { - QPluginLoader loader(pluginsDir.absoluteFilePath(fileName)); - QObject *possiblePlugin = loader.instance(); - if (Plugin *plugin = qobject_cast(possiblePlugin)) { - QString objectName = possiblePlugin->objectName(); - if (objectName.isEmpty()) - objectName = fileName; - - itemNames.append(objectName); - items.append(plugin); - } - } - - if (items.isEmpty()) { - QMessageBox::information(this, "No tank types found", "Please build the errorstateplugins directory"); - return; - } - - bool ok; -//! [1] - QString selectedName = QInputDialog::getItem(this, "Select a tank type", "Tank types", - itemNames, 0, false, &ok); -//! [1] - - if (ok && !selectedName.isEmpty()) { - int idx = itemNames.indexOf(selectedName); - if (Plugin *plugin = idx >= 0 ? items.at(idx) : 0) { - TankItem *tankItem = m_spawns.takeLast(); - tankItem->setObjectName(selectedName); - tankItem->setToolTip(selectedName); - m_scene->addItem(tankItem); - connect(tankItem, SIGNAL(cannonFired()), this, SLOT(addRocket())); - if (m_spawns.isEmpty()) - emit mapFull(); - - m_gameOverTransition->addTankItem(tankItem); - - QState *region = new QState(m_runningState); - region->setObjectName(QString::fromLatin1("region%1").arg(m_spawns.size())); -//! [2] - QState *pluginState = plugin->create(region, tankItem); -//! [2] - region->setInitialState(pluginState); - - // If the plugin has an error it is disabled -//! [4] - QState *errorState = new QState(region); - errorState->setObjectName(QString::fromLatin1("errorState%1").arg(m_spawns.size())); - errorState->assignProperty(tankItem, "enabled", false); - pluginState->setErrorState(errorState); -//! [4] - } - } -} - diff --git a/examples/statemachine/tankgame/mainwindow.h b/examples/statemachine/tankgame/mainwindow.h deleted file mode 100644 index 4ae8f7a..0000000 --- a/examples/statemachine/tankgame/mainwindow.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include - -QT_BEGIN_NAMESPACE -class QGraphicsScene; -class QStateMachine; -class QState; -QT_END_NAMESPACE -class GameOverTransition; -class TankItem; - -class MainWindow: public QMainWindow -{ - Q_OBJECT - Q_PROPERTY(bool started READ started WRITE setStarted) -public: - MainWindow(QWidget *parent = 0); - ~MainWindow(); - - void setStarted(bool b) { m_started = b; } - bool started() const { return m_started; } - -public slots: - void addTank(); - void addRocket(); - void runStep(); - void gameOver(); - -signals: - void mapFull(); - -private: - void init(); - void addWall(const QRectF &wall); - - QGraphicsScene *m_scene; - - QStateMachine *m_machine; - QState *m_runningState; - GameOverTransition *m_gameOverTransition; - - QList m_spawns; - QTime m_time; - - bool m_started : 1; -}; - -#endif - diff --git a/examples/statemachine/tankgame/plugin.h b/examples/statemachine/tankgame/plugin.h deleted file mode 100644 index ddd10b7..0000000 --- a/examples/statemachine/tankgame/plugin.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PLUGIN_H -#define PLUGIN_H - -#include - -QT_BEGIN_NAMESPACE -class QState; -QT_END_NAMESPACE -class Plugin -{ -public: - virtual ~Plugin() {} - - virtual QState *create(QState *parentState, QObject *tank) = 0; -}; - -QT_BEGIN_NAMESPACE -Q_DECLARE_INTERFACE(Plugin, "TankPlugin") -QT_END_NAMESPACE - -#endif diff --git a/examples/statemachine/tankgame/rocketitem.cpp b/examples/statemachine/tankgame/rocketitem.cpp deleted file mode 100644 index 3ace8e8..0000000 --- a/examples/statemachine/tankgame/rocketitem.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "rocketitem.h" -#include "tankitem.h" - -#include -#include - -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -RocketItem::RocketItem(QObject *parent) - : GameItem(parent), m_direction(0.0), m_distance(300.0) -{ -} - -QRectF RocketItem::boundingRect() const -{ - return QRectF(-1.0, -1.0, 2.0, 2.0); -} - -void RocketItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - painter->setBrush(Qt::black); - painter->drawEllipse(boundingRect()); -} - -void RocketItem::idle(qreal elapsed) -{ - qreal dist = elapsed * speed(); - - m_distance -= dist; - if (m_distance < 0.0) { - scene()->removeItem(this); - delete this; - return; - } - - qreal a = m_direction * M_PI / 180.0; - - qreal yd = dist * sin(a); - qreal xd = dist * sin(M_PI / 2.0 - a); - - QPointF requestedPosition = pos() + QPointF(xd, yd); - QGraphicsItem *collidedItem = 0; - QPointF nextPosition = tryMove(requestedPosition, 0, &collidedItem); - if (requestedPosition == nextPosition) { - setPos(nextPosition); - } else { - if (GameItem *gameItem = qgraphicsitem_cast(collidedItem)) { - TankItem *tankItem = qobject_cast(gameItem); - if (tankItem != 0) - tankItem->hitByRocket(); - } - - scene()->removeItem(this); - delete this; - } -} diff --git a/examples/statemachine/tankgame/rocketitem.h b/examples/statemachine/tankgame/rocketitem.h deleted file mode 100644 index 31146a6..0000000 --- a/examples/statemachine/tankgame/rocketitem.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ROCKETITEM_H -#define ROCKETITEM_H - -#include "gameitem.h" - -class RocketItem: public GameItem -{ - Q_OBJECT -public: - RocketItem(QObject *parent = 0); - - virtual void idle(qreal elapsed); - qreal speed() const { return 100.0; } - void setDirection(qreal direction) { m_direction = direction; } - -protected: - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - QRectF boundingRect() const; - -private: - qreal m_direction; - qreal m_distance; -}; - -#endif diff --git a/examples/statemachine/tankgame/tankgame.pro b/examples/statemachine/tankgame/tankgame.pro deleted file mode 100644 index 59415be..0000000 --- a/examples/statemachine/tankgame/tankgame.pro +++ /dev/null @@ -1,19 +0,0 @@ -HEADERS += mainwindow.h \ - plugin.h \ - tankitem.h \ - rocketitem.h \ - gameitem.h \ - gameovertransition.h -SOURCES += main.cpp \ - mainwindow.cpp \ - tankitem.cpp \ - rocketitem.cpp \ - gameitem.cpp \ - gameovertransition.cpp -CONFIG += console - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS tankgame.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame -INSTALLS += target sources diff --git a/examples/statemachine/tankgame/tankitem.cpp b/examples/statemachine/tankgame/tankitem.cpp deleted file mode 100644 index 393d65f..0000000 --- a/examples/statemachine/tankgame/tankitem.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "tankitem.h" - -#include -#include -#include - -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -class Action -{ -public: - Action(TankItem *item) : m_item(item) - { - } - - TankItem *item() const { return m_item; } - void setItem(TankItem *item) { m_item = item; } - - virtual bool apply(qreal timeDelta) = 0; - -private: - TankItem *m_item; -}; - -class MoveAction: public Action -{ -public: - MoveAction(TankItem *item, qreal distance) - : Action(item), m_distance(distance) - { - m_reverse = m_distance < 0.0; - } - - bool apply(qreal timeDelta) - { - qreal dist = timeDelta * item()->speed() * (m_reverse ? -1.0 : 1.0); - - bool done = false; - if (qAbs(m_distance) < qAbs(dist)) { - done = true; - dist = m_distance; - } - m_distance -= dist; - - qreal a = item()->direction() * M_PI / 180.0; - - qreal yd = dist * sin(a); - qreal xd = dist * sin(M_PI / 2.0 - a); - - item()->setPos(item()->pos() + QPointF(xd, yd)); - return !done; - } - -private: - qreal m_distance; - bool m_reverse; -}; - -class TurnAction: public Action -{ -public: - TurnAction(TankItem *item, qreal distance) - : Action(item), m_distance(distance) - { - m_reverse = m_distance < 0.0; - } - - bool apply(qreal timeDelta) - { - qreal dist = timeDelta * item()->angularSpeed() * (m_reverse ? -1.0 : 1.0); - bool done = false; - if (qAbs(m_distance) < qAbs(dist)) { - done = true; - dist = m_distance; - } - m_distance -= dist; - - item()->setDirection(item()->direction() + dist); - return !done; - } - -private: - qreal m_distance; - bool m_reverse; -}; - -TankItem::TankItem(QObject *parent) - : GameItem(parent), m_currentAction(0), m_currentDirection(0.0), m_enabled(true) -{ - connect(this, SIGNAL(cannonFired()), this, SIGNAL(actionCompleted())); -} - -void TankItem::idle(qreal elapsed) -{ - if (m_enabled) { - if (m_currentAction != 0) { - if (!m_currentAction->apply(elapsed)) { - setAction(0); - emit actionCompleted(); - } - - QGraphicsItem *item = 0; - qreal distance = distanceToObstacle(&item); - if (TankItem *tankItem = qgraphicsitem_cast(item)) - emit tankSpotted(tankItem->direction(), distance); - } - } -} - -void TankItem::hitByRocket() -{ - emit aboutToBeDestroyed(); - deleteLater(); -} - -void TankItem::setAction(Action *newAction) -{ - if (m_currentAction != 0) - delete m_currentAction; - - m_currentAction = newAction; -} - -void TankItem::fireCannon() -{ - emit cannonFired(); -} - -void TankItem::moveForwards(qreal length) -{ - setAction(new MoveAction(this, length)); -} - -void TankItem::moveBackwards(qreal length) -{ - setAction(new MoveAction(this, -length)); -} - -void TankItem::turn(qreal degrees) -{ - setAction(new TurnAction(this, degrees)); -} - -void TankItem::turnTo(qreal degrees) -{ - setAction(new TurnAction(this, degrees - direction())); -} - -void TankItem::stop() -{ - setAction(0); -} - -QVariant TankItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) -{ - if (change == ItemPositionChange && scene()) { - QPointF requestedPosition = value.toPointF(); - QLineF collidedLine; - QPointF nextPoint = tryMove(requestedPosition, &collidedLine); - if (nextPoint != requestedPosition) - emit collision(collidedLine); - return nextPoint; - } else { - return QGraphicsItem::itemChange(change, value); - } -} - - -void TankItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - QRectF brect = boundingRect(); - - painter->setBrush(m_color); - painter->setPen(Qt::black); - - // body - painter->drawRect(brect.adjusted(0.0, 4.0, -2.0, -4.0)); - - // cannon - QRectF cannonBase = brect.adjusted(10.0, 6.0, -12.0, -6.0); - painter->drawEllipse(cannonBase); - - painter->drawRect(QRectF(QPointF(cannonBase.center().x(), cannonBase.center().y() - 2.0), - QPointF(brect.right(), cannonBase.center().y() + 2.0))); - - // left track - painter->setBrush(QBrush(Qt::black, Qt::VerPattern)); - QRectF leftTrackRect = QRectF(brect.topLeft(), QPointF(brect.right() - 2.0, brect.top() + 4.0)); - painter->fillRect(leftTrackRect, Qt::darkYellow); - painter->drawRect(leftTrackRect); - - // right track - QRectF rightTrackRect = QRectF(QPointF(brect.left(), brect.bottom() - 4.0), - QPointF(brect.right() - 2.0, brect.bottom())); - painter->fillRect(rightTrackRect, Qt::darkYellow); - painter->drawRect(rightTrackRect); - - if (!m_enabled) { - painter->setPen(QPen(Qt::red, 5)); - - painter->drawEllipse(brect); - - QPainterPath path; - path.addEllipse(brect); - painter->setClipPath(path); - painter->drawLine(brect.topRight(), brect.bottomLeft()); - } -} - -QRectF TankItem::boundingRect() const -{ - return QRectF(-20.0, -10.0, 40.0, 20.0); -} - -qreal TankItem::direction() const -{ - return m_currentDirection; -} - -void TankItem::setDirection(qreal newDirection) -{ - int fullRotations = int(newDirection) / 360; - newDirection -= fullRotations * 360.0; - - qreal diff = newDirection - m_currentDirection; - m_currentDirection = newDirection; - rotate(diff); -} - -qreal TankItem::distanceToObstacle(QGraphicsItem **obstacle) const -{ - qreal dist = sqrt(pow(scene()->sceneRect().width(), 2) + pow(scene()->sceneRect().height(), 2)); - - qreal a = m_currentDirection * M_PI / 180.0; - - qreal yd = dist * sin(a); - qreal xd = dist * sin(M_PI / 2.0 - a); - - QPointF requestedPosition = pos() + QPointF(xd, yd); - QGraphicsItem *collidedItem = 0; - QPointF nextPosition = tryMove(requestedPosition, 0, &collidedItem); - if (collidedItem != 0) { - if (obstacle != 0) - *obstacle = collidedItem; - - QPointF d = nextPosition - pos(); - return sqrt(pow(d.x(), 2) + pow(d.y(), 2)); - } else { - return 0.0; - } -} - -qreal TankItem::distanceToObstacle() const -{ - return distanceToObstacle(0); -} - diff --git a/examples/statemachine/tankgame/tankitem.h b/examples/statemachine/tankgame/tankitem.h deleted file mode 100644 index 942fca8..0000000 --- a/examples/statemachine/tankgame/tankitem.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TANKITEM_H -#define TANKITEM_H - -#include "gameitem.h" - -#include - -class Action; -class TankItem: public GameItem -{ - Q_OBJECT - Q_PROPERTY(bool enabled READ enabled WRITE setEnabled) - Q_PROPERTY(qreal direction READ direction WRITE turnTo) - Q_PROPERTY(qreal distanceToObstacle READ distanceToObstacle) -public: - TankItem(QObject *parent = 0); - - void setColor(const QColor &color) { m_color = color; } - QColor color() const { return m_color; } - - void idle(qreal elapsed); - void setDirection(qreal newDirection); - - qreal speed() const { return 90.0; } - qreal angularSpeed() const { return 90.0; } - - QRectF boundingRect() const; - - void hitByRocket(); - - void setEnabled(bool b) { m_enabled = b; } - bool enabled() const { return m_enabled; } - - qreal direction() const; - qreal distanceToObstacle() const; - qreal distanceToObstacle(QGraphicsItem **item) const; - -//! [0] -signals: - void tankSpotted(qreal direction, qreal distance); - void collision(const QLineF &collidedLine); - void actionCompleted(); - void cannonFired(); - void aboutToBeDestroyed(); - -public slots: - void moveForwards(qreal length = 10.0); - void moveBackwards(qreal length = 10.0); - void turn(qreal degrees = 30.0); - void turnTo(qreal degrees = 0.0); - void stop(); - void fireCannon(); -//! [0] - -protected: - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value); - -private: - void setAction(Action *newAction); - - Action *m_currentAction; - qreal m_currentDirection; - QColor m_color; - bool m_enabled; -}; - -#endif diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai.pro b/examples/statemachine/tankgameplugins/random_ai/random_ai.pro deleted file mode 100644 index 5bc0b26..0000000 --- a/examples/statemachine/tankgameplugins/random_ai/random_ai.pro +++ /dev/null @@ -1,13 +0,0 @@ -TEMPLATE = lib -CONFIG += plugin -INCLUDEPATH += ../.. -HEADERS = random_ai_plugin.h -SOURCES = random_ai_plugin.cpp -TARGET = $$qtLibraryTarget(random_ai) -DESTDIR = ../../tankgame/plugins - -#! [0] -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS random_ai.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/random_ai \ No newline at end of file diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp deleted file mode 100644 index d360de9..0000000 --- a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "random_ai_plugin.h" - -#include -#include - -#include - -QState *RandomAiPlugin::create(QState *parentState, QObject *tank) -{ - qsrand(uint(time(NULL))); - - QState *topLevel = new QState(parentState); - - QState *selectNextActionState = new SelectActionState(topLevel); - topLevel->setInitialState(selectNextActionState); - - QState *fireState = new RandomDistanceState(topLevel); - connect(fireState, SIGNAL(distanceComputed(qreal)), tank, SLOT(fireCannon())); - selectNextActionState->addTransition(selectNextActionState, SIGNAL(fireSelected()), fireState); - - QState *moveForwardsState = new RandomDistanceState(topLevel); - connect(moveForwardsState, SIGNAL(distanceComputed(qreal)), tank, SLOT(moveForwards(qreal))); - selectNextActionState->addTransition(selectNextActionState, SIGNAL(moveForwardsSelected()), moveForwardsState); - - QState *moveBackwardsState = new RandomDistanceState(topLevel); - connect(moveBackwardsState, SIGNAL(distanceComputed(qreal)), tank, SLOT(moveBackwards(qreal))); - selectNextActionState->addTransition(selectNextActionState, SIGNAL(moveBackwardsSelected()), moveBackwardsState); - - QState *turnState = new RandomDistanceState(topLevel); - connect(turnState, SIGNAL(distanceComputed(qreal)), tank, SLOT(turn(qreal))); - selectNextActionState->addTransition(selectNextActionState, SIGNAL(turnSelected()), turnState); - - topLevel->addTransition(tank, SIGNAL(actionCompleted()), selectNextActionState); - - return topLevel; -} - -Q_EXPORT_PLUGIN2(random_ai, RandomAiPlugin) diff --git a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h b/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h deleted file mode 100644 index 9faeeac..0000000 --- a/examples/statemachine/tankgameplugins/random_ai/random_ai_plugin.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef RANDOM_AI_PLUGIN_H -#define RANDOM_AI_PLUGIN_H - -#include -#include - -#include - -class SelectActionState: public QState -{ - Q_OBJECT -public: - SelectActionState(QState *parent = 0) : QState(parent) - { - } - -signals: - void fireSelected(); - void moveForwardsSelected(); - void moveBackwardsSelected(); - void turnSelected(); - -protected: - void onEntry(QEvent *) - { - int rand = qrand() % 4; - switch (rand) { - case 0: emit fireSelected(); break; - case 1: emit moveForwardsSelected(); break; - case 2: emit moveBackwardsSelected(); break; - case 3: emit turnSelected(); break; - }; - } -}; - -class RandomDistanceState: public QState -{ - Q_OBJECT -public: - RandomDistanceState(QState *parent = 0) : QState(parent) - { - } - -signals: - void distanceComputed(qreal distance); - -protected: - void onEntry(QEvent *) - { - emit distanceComputed(qreal(qrand() % 180)); - } -}; - -class RandomAiPlugin: public QObject, public Plugin -{ - Q_OBJECT - Q_INTERFACES(Plugin) -public: - RandomAiPlugin() { setObjectName("Random"); } - - virtual QState *create(QState *parentState, QObject *tank); -}; - -#endif // RANDOM_AI_PLUGIN_H diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp deleted file mode 100644 index 6aae015..0000000 --- a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "seek_ai.h" - -QState *SeekAi::create(QState *parentState, QObject *tank) -{ - QState *topLevel = new QState(parentState); - topLevel->setObjectName("topLevel"); - - QState *seek = new QState(topLevel); - seek->setObjectName("seek"); - topLevel->setInitialState(seek); - - QState *lookForNearestWall = new SearchState(tank, seek); - lookForNearestWall->setObjectName("lookForNearestWall"); - seek->setInitialState(lookForNearestWall); - - QState *driveToFirstObstacle = new QState(seek); - driveToFirstObstacle->setObjectName("driveToFirstObstacle"); - lookForNearestWall->addTransition(lookForNearestWall, SIGNAL(nearestObstacleStraightAhead()), - driveToFirstObstacle); - - QState *drive = new QState(driveToFirstObstacle); - drive->setObjectName("drive"); - driveToFirstObstacle->setInitialState(drive); - connect(drive, SIGNAL(entered()), tank, SLOT(moveForwards())); - connect(drive, SIGNAL(exited()), tank, SLOT(stop())); - - // Go in loop - QState *finishedDriving = new QState(driveToFirstObstacle); - finishedDriving->setObjectName("finishedDriving"); - drive->addTransition(tank, SIGNAL(actionCompleted()), finishedDriving); - finishedDriving->addTransition(drive); - - QState *turnTo = new QState(seek); - turnTo->setObjectName("turnTo"); - driveToFirstObstacle->addTransition(new CollisionTransition(tank, turnTo)); - - turnTo->addTransition(tank, SIGNAL(actionCompleted()), driveToFirstObstacle); - - ChaseState *chase = new ChaseState(tank, topLevel); - chase->setObjectName("chase"); - seek->addTransition(new TankSpottedTransition(tank, chase)); - chase->addTransition(chase, SIGNAL(finished()), driveToFirstObstacle); - chase->addTransition(new TankSpottedTransition(tank, chase)); - - return topLevel; -} - -Q_EXPORT_PLUGIN2(seek_ai, SeekAi) diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h deleted file mode 100644 index e44ad07..0000000 --- a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.h +++ /dev/null @@ -1,249 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SEEK_AI_H -#define SEEK_AI_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -class SearchState: public QState -{ - Q_OBJECT -public: - SearchState(QObject *tank, QState *parentState = 0) - : QState(parentState), - m_tank(tank), - m_distanceToTurn(360.0), - m_nearestDistance(-1.0), - m_directionOfNearestObstacle(0.0) - { - } - -public slots: - void turnAlittle() - { - qreal dist = m_tank->property("distanceToObstacle").toDouble(); - - if (m_nearestDistance < 0.0 || dist < m_nearestDistance) { - m_nearestDistance = dist; - m_directionOfNearestObstacle = m_tank->property("direction").toDouble(); - } - - m_distanceToTurn -= 10.0; - if (m_distanceToTurn < 0.0) { - disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(turnAlittle())); - connect(m_tank, SIGNAL(actionCompleted()), this, SIGNAL(nearestObstacleStraightAhead())); - m_tank->setProperty("direction", m_directionOfNearestObstacle); - } - - qreal currentDirection = m_tank->property("direction").toDouble(); - m_tank->setProperty("direction", currentDirection + 10.0); - } - -signals: - void nearestObstacleStraightAhead(); - -protected: - void onEntry(QEvent *) - { - connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(turnAlittle())); - turnAlittle(); - } - - void onExit(QEvent *) - { - disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(turnAlittle())); - disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(nearestObstacleStraightAhead())); - } - -private: - QObject *m_tank; - - qreal m_distanceToTurn; - qreal m_nearestDistance; - qreal m_directionOfNearestObstacle; -}; - -class CollisionTransition: public QSignalTransition -{ -public: - CollisionTransition(QObject *tank, QState *turnTo) - : QSignalTransition(tank, SIGNAL(collision(QLineF))), - m_tank(tank), - m_turnTo(turnTo) - { - setTargetState(turnTo); - } - -protected: - bool eventTest(QEvent *event) - { - bool b = QSignalTransition::eventTest(event); - if (b) { - QSignalEvent *se = static_cast(event); - m_lastLine = se->arguments().at(0).toLineF(); - } - return b; - } - - void onTransition(QEvent *) - { - qreal angleOfWall = m_lastLine.angle(); - - qreal newDirection; - if (qrand() % 2 == 0) - newDirection = angleOfWall; - else - newDirection = angleOfWall - 180.0; - - m_turnTo->assignProperty(m_tank, "direction", newDirection); - } - -private: - QLineF m_lastLine; - QObject *m_tank; - QState *m_turnTo; -}; - -class ChaseState: public QState -{ - class GoToLocationState: public QState - { - public: - GoToLocationState(QObject *tank, QState *parentState = 0) - : QState(parentState), m_tank(tank), m_distance(0.0) - { - } - - void setDistance(qreal distance) { m_distance = distance; } - - protected: - void onEntry() - { - QMetaObject::invokeMethod(m_tank, "moveForwards", Q_ARG(qreal, m_distance)); - } - - private: - QObject *m_tank; - qreal m_distance; - }; - -public: - ChaseState(QObject *tank, QState *parentState = 0) : QState(parentState), m_tank(tank) - { - QState *fireCannon = new QState(this); - fireCannon->setObjectName("fireCannon"); - connect(fireCannon, SIGNAL(entered()), tank, SLOT(fireCannon())); - setInitialState(fireCannon); - - m_goToLocation = new GoToLocationState(tank, this); - m_goToLocation->setObjectName("goToLocation"); - fireCannon->addTransition(tank, SIGNAL(actionCompleted()), m_goToLocation); - - m_turnToDirection = new QState(this); - m_turnToDirection->setObjectName("turnToDirection"); - m_goToLocation->addTransition(tank, SIGNAL(actionCompleted()), m_turnToDirection); - - QFinalState *finalState = new QFinalState(this); - finalState->setObjectName("finalState"); - m_turnToDirection->addTransition(tank, SIGNAL(actionCompleted()), finalState); - } - - void setDirection(qreal direction) - { - m_turnToDirection->assignProperty(m_tank, "direction", direction); - } - - void setDistance(qreal distance) - { - m_goToLocation->setDistance(distance); - } - -private: - QObject *m_tank; - GoToLocationState *m_goToLocation; - QState *m_turnToDirection; - -}; - -class TankSpottedTransition: public QSignalTransition -{ -public: - TankSpottedTransition(QObject *tank, ChaseState *target) : QSignalTransition(tank, SIGNAL(tankSpotted(qreal,qreal))), m_chase(target) - { - setTargetState(target); - } - -protected: - bool eventTest(QEvent *event) - { - bool b = QSignalTransition::eventTest(event); - if (b) { - QSignalEvent *se = static_cast(event); - m_chase->setDirection(se->arguments().at(0).toDouble()); - m_chase->setDistance(se->arguments().at(1).toDouble()); - } - return b; - } - -private: - ChaseState *m_chase; -}; - -class SeekAi: public QObject, public Plugin -{ - Q_OBJECT - Q_INTERFACES(Plugin) -public: - SeekAi() { setObjectName("Seek and destroy"); } - - virtual QState *create(QState *parentState, QObject *tank); -}; - -#endif diff --git a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro b/examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro deleted file mode 100644 index 0d8bf2e..0000000 --- a/examples/statemachine/tankgameplugins/seek_ai/seek_ai.pro +++ /dev/null @@ -1,13 +0,0 @@ -TEMPLATE = lib -CONFIG += plugin -INCLUDEPATH += ../.. -HEADERS = seek_ai.h -SOURCES = seek_ai.cpp -TARGET = $$qtLibraryTarget(seek_ai) -DESTDIR = ../../tankgame/plugins - -#! [0] -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS seek_ai.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/seek_ai \ No newline at end of file diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp deleted file mode 100644 index 581a6b2..0000000 --- a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "spin_ai.h" - -#include - -QState *SpinAi::create(QState *parentState, QObject *tank) -{ - QState *topLevel = new QState(parentState); - QState *spinState = new SpinState(tank, topLevel); - topLevel->setInitialState(spinState); - - // When tank is spotted, fire two times and go back to spin state - QState *fireState = new QState(topLevel); - - QState *fireOnce = new QState(fireState); - fireState->setInitialState(fireOnce); - connect(fireOnce, SIGNAL(entered()), tank, SLOT(fireCannon())); - - QState *fireTwice = new QState(fireState); - connect(fireTwice, SIGNAL(entered()), tank, SLOT(fireCannon())); - - fireOnce->addTransition(tank, SIGNAL(actionCompleted()), fireTwice); - fireTwice->addTransition(tank, SIGNAL(actionCompleted()), spinState); - - spinState->addTransition(tank, SIGNAL(tankSpotted(qreal,qreal)), fireState); - - return topLevel; -} - -Q_EXPORT_PLUGIN2(spin_ai, SpinAi) diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h deleted file mode 100644 index 652e8b8..0000000 --- a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SPIN_AI_H -#define SPIN_AI_H - -#include - -#include -#include -#include - -class SpinState: public QState -{ - Q_OBJECT -public: - SpinState(QObject *tank, QState *parent) : QState(parent), m_tank(tank) - { - } - -public slots: - void spin() - { - m_tank->setProperty("direction", m_tank->property("direction").toDouble() + 90.0); - } - -protected: - void onEntry(QEvent *) - { - connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); - spin(); - } - - void onExit(QEvent *) - { - disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); - } - -private: - QObject *m_tank; - -}; - -class SpinAi: public QObject, public Plugin -{ - Q_OBJECT - Q_INTERFACES(Plugin) -public: - SpinAi() { setObjectName("Spin and destroy"); } - - virtual QState *create(QState *parentState, QObject *tank); -}; - -#endif diff --git a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro b/examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro deleted file mode 100644 index 8ab4da0..0000000 --- a/examples/statemachine/tankgameplugins/spin_ai/spin_ai.pro +++ /dev/null @@ -1,13 +0,0 @@ -TEMPLATE = lib -CONFIG += plugin -INCLUDEPATH += ../.. -HEADERS = spin_ai.h -SOURCES = spin_ai.cpp -TARGET = $$qtLibraryTarget(spin_ai) -DESTDIR = ../../tankgame/plugins - -#! [0] -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS spin_ai.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/spin_ai \ No newline at end of file diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp deleted file mode 100644 index 19137b2..0000000 --- a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "spin_ai_with_error.h" - -#include - -QState *SpinAiWithError::create(QState *parentState, QObject *tank) -{ - QState *topLevel = new QState(parentState); - QState *spinState = new SpinState(tank, topLevel); - topLevel->setInitialState(spinState); - - // When tank is spotted, fire two times and go back to spin state - // (no initial state set for fireState will lead to run-time error in machine) - QState *fireState = new QState(topLevel); - - QState *fireOnce = new QState(fireState); - connect(fireOnce, SIGNAL(entered()), tank, SLOT(fireCannon())); - - QState *fireTwice = new QState(fireState); - connect(fireTwice, SIGNAL(entered()), tank, SLOT(fireCannon())); - - fireOnce->addTransition(tank, SIGNAL(actionCompleted()), fireTwice); - fireTwice->addTransition(tank, SIGNAL(actionCompleted()), spinState); - - spinState->addTransition(tank, SIGNAL(tankSpotted(qreal,qreal)), fireState); - - return topLevel; -} - -Q_EXPORT_PLUGIN2(spin_ai_with_error, SpinAiWithError) diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h deleted file mode 100644 index e040bf2..0000000 --- a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SPIN_AI_WITH_ERROR_H -#define SPIN_AI_WITH_ERROR_H - -#include - -#include -#include -#include - -class SpinState: public QState -{ - Q_OBJECT -public: - SpinState(QObject *tank, QState *parent) : QState(parent), m_tank(tank) - { - } - -public slots: - void spin() - { - m_tank->setProperty("direction", m_tank->property("direction").toDouble() + 90.0); - } - -protected: - void onEntry(QEvent *) - { - connect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); - spin(); - } - - void onExit(QEvent *) - { - disconnect(m_tank, SIGNAL(actionCompleted()), this, SLOT(spin())); - } - -private: - QObject *m_tank; - -}; - -class SpinAiWithError: public QObject, public Plugin -{ - Q_OBJECT - Q_INTERFACES(Plugin) -public: - SpinAiWithError() { setObjectName("Spin and destroy with runtime error in state machine"); } - - virtual QState *create(QState *parentState, QObject *tank); -}; - -#endif diff --git a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro b/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro deleted file mode 100644 index 124cf98..0000000 --- a/examples/statemachine/tankgameplugins/spin_ai_with_error/spin_ai_with_error.pro +++ /dev/null @@ -1,13 +0,0 @@ -TEMPLATE = lib -CONFIG += plugin -INCLUDEPATH += ../.. -HEADERS = spin_ai_with_error.h -SOURCES = spin_ai_with_error.cpp -TARGET = $$qtLibraryTarget(spin_ai_with_error) -DESTDIR = ../../tankgame/plugins - -#! [0] -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgame/plugins -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS spin_ai_with_error.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins/spin_ai_with_error \ No newline at end of file diff --git a/examples/statemachine/tankgameplugins/tankgameplugins.pro b/examples/statemachine/tankgameplugins/tankgameplugins.pro deleted file mode 100644 index a098e03..0000000 --- a/examples/statemachine/tankgameplugins/tankgameplugins.pro +++ /dev/null @@ -1,11 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS = random_ai \ - spin_ai_with_error \ - spin_ai \ - seek_ai - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS tankgameplugins.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/tankgameplugins -INSTALLS += target sources diff --git a/examples/statemachine/trafficlight/main.cpp b/examples/statemachine/trafficlight/main.cpp deleted file mode 100644 index 8a46fff..0000000 --- a/examples/statemachine/trafficlight/main.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#ifdef QT_STATEMACHINE_SOLUTION -#include -#include -#include -#endif - -//! [0] -class LightWidget : public QWidget -{ - Q_OBJECT - Q_PROPERTY(bool on READ isOn WRITE setOn) -public: - LightWidget(const QColor &color, QWidget *parent = 0) - : QWidget(parent), m_color(color), m_on(false) {} - - bool isOn() const - { return m_on; } - void setOn(bool on) - { - if (on == m_on) - return; - m_on = on; - update(); - } - -public slots: - void turnOff() { setOn(false); } - void turnOn() { setOn(true); } - -protected: - virtual void paintEvent(QPaintEvent *) - { - if (!m_on) - return; - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - painter.setBrush(m_color); - painter.drawEllipse(0, 0, width(), height()); - } - -private: - QColor m_color; - bool m_on; -}; -//! [0] - -//! [1] -class TrafficLightWidget : public QWidget -{ -public: - TrafficLightWidget(QWidget *parent = 0) - : QWidget(parent) - { - QVBoxLayout *vbox = new QVBoxLayout(this); - m_red = new LightWidget(Qt::red); - vbox->addWidget(m_red); - m_yellow = new LightWidget(Qt::yellow); - vbox->addWidget(m_yellow); - m_green = new LightWidget(Qt::green); - vbox->addWidget(m_green); - QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::black); - setPalette(pal); - setAutoFillBackground(true); - } - - LightWidget *redLight() const - { return m_red; } - LightWidget *yellowLight() const - { return m_yellow; } - LightWidget *greenLight() const - { return m_green; } - -private: - LightWidget *m_red; - LightWidget *m_yellow; - LightWidget *m_green; -}; -//! [1] - -//! [2] -QState *createLightState(LightWidget *light, int duration, QState *parent = 0) -{ - QState *lightState = new QState(parent); - QTimer *timer = new QTimer(lightState); - timer->setInterval(duration); - timer->setSingleShot(true); - QState *timing = new QState(lightState); - QObject::connect(timing, SIGNAL(entered()), light, SLOT(turnOn())); - QObject::connect(timing, SIGNAL(entered()), timer, SLOT(start())); - QObject::connect(timing, SIGNAL(exited()), light, SLOT(turnOff())); - QFinalState *done = new QFinalState(lightState); - timing->addTransition(timer, SIGNAL(timeout()), done); - lightState->setInitialState(timing); - return lightState; -} -//! [2] - -//! [3] -class TrafficLight : public QWidget -{ -public: - TrafficLight(QWidget *parent = 0) - : QWidget(parent) - { - QVBoxLayout *vbox = new QVBoxLayout(this); - TrafficLightWidget *widget = new TrafficLightWidget(); - vbox->addWidget(widget); - vbox->setMargin(0); - - QStateMachine *machine = new QStateMachine(this); - QState *redGoingYellow = createLightState(widget->redLight(), 3000); - redGoingYellow->setObjectName("redGoingYellow"); - QState *yellowGoingGreen = createLightState(widget->yellowLight(), 1000); - yellowGoingGreen->setObjectName("yellowGoingGreen"); - redGoingYellow->addTransition(redGoingYellow, SIGNAL(finished()), yellowGoingGreen); - QState *greenGoingYellow = createLightState(widget->greenLight(), 3000); - greenGoingYellow->setObjectName("greenGoingYellow"); - yellowGoingGreen->addTransition(yellowGoingGreen, SIGNAL(finished()), greenGoingYellow); - QState *yellowGoingRed = createLightState(widget->yellowLight(), 1000); - yellowGoingRed->setObjectName("yellowGoingRed"); - greenGoingYellow->addTransition(greenGoingYellow, SIGNAL(finished()), yellowGoingRed); - yellowGoingRed->addTransition(yellowGoingRed, SIGNAL(finished()), redGoingYellow); - - machine->addState(redGoingYellow); - machine->addState(yellowGoingGreen); - machine->addState(greenGoingYellow); - machine->addState(yellowGoingRed); - machine->setInitialState(redGoingYellow); - machine->start(); - } -}; -//! [3] - -//! [4] -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - TrafficLight widget; - widget.resize(110, 300); - widget.show(); - - return app.exec(); -} -//! [4] - -#include "main.moc" diff --git a/examples/statemachine/trafficlight/trafficlight.pro b/examples/statemachine/trafficlight/trafficlight.pro deleted file mode 100644 index 684575a..0000000 --- a/examples/statemachine/trafficlight/trafficlight.pro +++ /dev/null @@ -1,7 +0,0 @@ -SOURCES = main.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/trafficlight -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS trafficlight.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/trafficlight -INSTALLS += target sources diff --git a/examples/statemachine/twowaybutton/main.cpp b/examples/statemachine/twowaybutton/main.cpp deleted file mode 100644 index a2c6e45..0000000 --- a/examples/statemachine/twowaybutton/main.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#ifdef QT_STATEMACHINE_SOLUTION -#include -#include -#endif - -//! [0] -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - QPushButton button; - QStateMachine machine; -//! [0] - -//! [1] - QState *off = new QState(); - off->assignProperty(&button, "text", "Off"); - off->setObjectName("off"); - - QState *on = new QState(); - on->setObjectName("on"); - on->assignProperty(&button, "text", "On"); -//! [1] - -//! [2] - off->addTransition(&button, SIGNAL(clicked()), on); - on->addTransition(&button, SIGNAL(clicked()), off); -//! [2] - -//! [3] - machine.addState(off); - machine.addState(on); -//! [3] - -//! [4] - machine.setInitialState(off); - machine.start(); -//! [4] - -//! [5] - button.resize(100, 50); - button.show(); - return app.exec(); -} -//! [5] diff --git a/examples/statemachine/twowaybutton/twowaybutton.pro b/examples/statemachine/twowaybutton/twowaybutton.pro deleted file mode 100644 index f6cbc57..0000000 --- a/examples/statemachine/twowaybutton/twowaybutton.pro +++ /dev/null @@ -1,7 +0,0 @@ -SOURCES = main.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/statemachine/twowaybutton -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS twowaybutton.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/statemachine/twowaybutton -INSTALLS += target sources diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index 78c947d..03582fc 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -16,7 +16,7 @@ QMAKE_LEX = flex QMAKE_LEXFLAGS = QMAKE_YACC = byacc QMAKE_YACCFLAGS = -d -QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738 +QMAKE_CFLAGS = -nologo -Zm200 /Qprec QMAKE_CFLAGS_WARN_ON = -W3 /Qwd673 QMAKE_CFLAGS_WARN_OFF = -W0 /Qwd673 QMAKE_CFLAGS_RELEASE = -O2 -MD diff --git a/src/3rdparty/easing/easing.cpp b/src/3rdparty/easing/easing.cpp deleted file mode 100644 index 81af40f..0000000 --- a/src/3rdparty/easing/easing.cpp +++ /dev/null @@ -1,670 +0,0 @@ -/* -Disclaimer for Robert Penner's Easing Equations license: - -TERMS OF USE - EASING EQUATIONS - -Open source under the BSD License. - -Copyright © 2001 Robert Penner -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif -#ifndef M_PI_2 -#define M_PI_2 (M_PI / 2) -#endif - -QT_USE_NAMESPACE - -/** - * Easing equation function for a simple linear tweening, with no easing. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeNone(qreal progress) -{ - return progress; -} - -/** - * Easing equation function for a quadratic (t^2) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInQuad(qreal t) -{ - return t*t; -} - -/** -* Easing equation function for a quadratic (t^2) easing out: decelerating to zero velocity. -* -* @param t Current time (in frames or seconds). -* @return The correct value. -*/ -static qreal easeOutQuad(qreal t) -{ - return -t*(t-2); -} - -/** - * Easing equation function for a quadratic (t^2) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInOutQuad(qreal t) -{ - t*=2.0; - if (t < 1) { - return t*t/qreal(2); - } else { - --t; - return -0.5 * (t*(t-2) - 1); - } -} - -/** - * Easing equation function for a quadratic (t^2) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutInQuad(qreal t) -{ - if (t < 0.5) return easeOutQuad (t*2)/2; - return easeInQuad((2*t)-1)/2 + 0.5; -} - -/** - * Easing equation function for a cubic (t^3) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInCubic(qreal t) -{ - return t*t*t; -} - -/** - * Easing equation function for a cubic (t^3) easing out: decelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutCubic(qreal t) -{ - t-=1.0; - return t*t*t + 1; -} - -/** - * Easing equation function for a cubic (t^3) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInOutCubic(qreal t) -{ - t*=2.0; - if(t < 1) { - return 0.5*t*t*t; - } else { - t -= qreal(2.0); - return 0.5*(t*t*t + 2); - } -} - -/** - * Easing equation function for a cubic (t^3) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutInCubic(qreal t) -{ - if (t < 0.5) return easeOutCubic (2*t)/2; - return easeInCubic(2*t - 1)/2 + 0.5; -} - -/** - * Easing equation function for a quartic (t^4) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInQuart(qreal t) -{ - return t*t*t*t; -} - -/** - * Easing equation function for a quartic (t^4) easing out: decelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutQuart(qreal t) -{ - t-= qreal(1.0); - return - (t*t*t*t- 1); -} - -/** - * Easing equation function for a quartic (t^4) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInOutQuart(qreal t) -{ - t*=2; - if (t < 1) return 0.5*t*t*t*t; - else { - t -= 2.0f; - return -0.5 * (t*t*t*t- 2); - } -} - -/** - * Easing equation function for a quartic (t^4) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutInQuart(qreal t) -{ - if (t < 0.5) return easeOutQuart (2*t)/2; - return easeInQuart(2*t-1)/2 + 0.5; -} - -/** - * Easing equation function for a quintic (t^5) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInQuint(qreal t) -{ - return t*t*t*t*t; -} - -/** - * Easing equation function for a quintic (t^5) easing out: decelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutQuint(qreal t) -{ - t-=1.0; - return t*t*t*t*t + 1; -} - -/** - * Easing equation function for a quintic (t^5) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInOutQuint(qreal t) -{ - t*=2.0; - if (t < 1) return 0.5*t*t*t*t*t; - else { - t -= 2.0; - return 0.5*(t*t*t*t*t + 2); - } -} - -/** - * Easing equation function for a quintic (t^5) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutInQuint(qreal t) -{ - if (t < 0.5) return easeOutQuint (2*t)/2; - return easeInQuint(2*t - 1)/2 + 0.5; -} - -/** - * Easing equation function for a sinusoidal (sin(t)) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInSine(qreal t) -{ - return (t == 1.0) ? 1.0 : -::cos(t * M_PI_2) + 1.0; -} - -/** - * Easing equation function for a sinusoidal (sin(t)) easing out: decelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutSine(qreal t) -{ - return ::sin(t* M_PI_2); -} - -/** - * Easing equation function for a sinusoidal (sin(t)) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInOutSine(qreal t) -{ - return -0.5 * (::cos(M_PI*t) - 1); -} - -/** - * Easing equation function for a sinusoidal (sin(t)) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutInSine(qreal t) -{ - if (t < 0.5) return easeOutSine (2*t)/2; - return easeInSine(2*t - 1)/2 + 0.5; -} - -/** - * Easing equation function for an exponential (2^t) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInExpo(qreal t) -{ - return (t==0 || t == 1.0) ? t : ::qPow(2.0, 10 * (t - 1)) - qreal(0.001); -} - -/** - * Easing equation function for an exponential (2^t) easing out: decelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutExpo(qreal t) -{ - return (t==1.0) ? 1.0 : 1.001 * (-::qPow(2.0f, -10 * t) + 1); -} - -/** - * Easing equation function for an exponential (2^t) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInOutExpo(qreal t) -{ - if (t==0.0) return qreal(0.0); - if (t==1.0) return qreal(1.0); - t*=2.0; - if (t < 1) return 0.5 * ::qPow(qreal(2.0), 10 * (t - 1)) - 0.0005; - return 0.5 * 1.0005 * (-::qPow(qreal(2.0), -10 * (t - 1)) + 2); -} - -/** - * Easing equation function for an exponential (2^t) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutInExpo(qreal t) -{ - if (t < 0.5) return easeOutExpo (2*t)/2; - return easeInExpo(2*t - 1)/2 + 0.5; -} - -/** - * Easing equation function for a circular (sqrt(1-t^2)) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInCirc(qreal t) -{ - return -(::sqrt(1 - t*t) - 1); -} - -/** - * Easing equation function for a circular (sqrt(1-t^2)) easing out: decelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutCirc(qreal t) -{ - t-= qreal(1.0); - return ::sqrt(1 - t* t); -} - -/** - * Easing equation function for a circular (sqrt(1-t^2)) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeInOutCirc(qreal t) -{ - t*=qreal(2.0); - if (t < 1) { - return -0.5 * (::sqrt(1 - t*t) - 1); - } else { - t -= qreal(2.0); - return 0.5 * (::sqrt(1 - t*t) + 1); - } -} - -/** - * Easing equation function for a circular (sqrt(1-t^2)) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @return The correct value. - */ -static qreal easeOutInCirc(qreal t) -{ - if (t < 0.5) return easeOutCirc (2*t)/2; - return easeInCirc(2*t - 1)/2 + 0.5; -} - -static qreal easeInElastic_helper(qreal t, qreal b, qreal c, qreal d, qreal a, qreal p) -{ - if (t==0) return b; - qreal t_adj = (qreal)t / (qreal)d; - if (t_adj==1) return b+c; - - qreal s; - if(a < ::fabs(c)) { - a = c; - s = p / 4.0f; - } else { - s = p / (2 * M_PI) * ::asin(c / a); - } - - t_adj -= 1.0f; - return -(a*::qPow(2.0f,10*t_adj) * ::sin( (t_adj*d-s)*(2*M_PI)/p )) + b; -} - -/** - * Easing equation function for an elastic (exponentially decaying sine wave) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @param a Amplitude. - * @param p Period. - * @return The correct value. - */ -static qreal easeInElastic(qreal t, qreal a, qreal p) -{ - return easeInElastic_helper(t, 0, 1, 1, a, p); -} - -static qreal easeOutElastic_helper(qreal t, qreal /*b*/, qreal c, qreal /*d*/, qreal a, qreal p) -{ - if (t==0) return 0; - if (t==1) return c; - - qreal s; - if(a < c) { - a = c; - s = p / 4.0f; - } else { - s = p / (2 * M_PI) * ::asin(c / a); - } - - return (a*::qPow(2.0f,-10*t) * ::sin( (t-s)*(2*M_PI)/p ) + c); -} - -/** - * Easing equation function for an elastic (exponentially decaying sine wave) easing out: decelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @param a Amplitude. - * @param p Period. - * @return The correct value. - */ -static qreal easeOutElastic(qreal t, qreal a, qreal p) -{ - return easeOutElastic_helper(t, 0, 1, 1, a, p); -} - -/** - * Easing equation function for an elastic (exponentially decaying sine wave) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @param a Amplitude. - * @param p Period. - * @return The correct value. - */ -static qreal easeInOutElastic(qreal t, qreal a, qreal p) -{ - if (t==0) return 0.0; - t*=2.0; - if (t==2) return 1.0; - - qreal s; - if(a < 1.0) { - a = 1.0; - s = p / 4.0f; - } else { - s = p / (2 * M_PI) * ::asin(1.0 / a); - } - - if (t < 1) return -.5*(a*::qPow(2.0f,10*(t-1)) * ::sin( (t-1-s)*(2*M_PI)/p )); - return a*::qPow(2.0f,-10*(t-1)) * ::sin( (t-1-s)*(2*M_PI)/p )*.5 + 1.0; -} - -/** - * Easing equation function for an elastic (exponentially decaying sine wave) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @param a Amplitude. - * @param p Period. - * @return The correct value. - */ -static qreal easeOutInElastic(qreal t, qreal a, qreal p) -{ - if (t < 0.5) return easeOutElastic_helper(t*2, 0, 0.5, 1.0, a, p); - return easeInElastic_helper(2*t - 1.0, 0.5, 0.5, 1.0, a, p); -} - -/** - * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). - * @return The correct value. - */ -static qreal easeInBack(qreal t, qreal s) -{ - return t*t*((s+1)*t - s); -} - -/** - * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out: decelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). - * @return The correct value. - */ -static qreal easeOutBack(qreal t, qreal s) -{ - t-= qreal(1.0); - return t*t*((s+1)*t+ s) + 1; -} - -/** - * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). - * @return The correct value. - */ -static qreal easeInOutBack(qreal t, qreal s) -{ - t *= 2.0; - if (t < 1) { - s *= 1.525f; - return 0.5*(t*t*((s+1)*t - s)); - } else { - t -= 2; - s *= 1.525f; - return 0.5*(t*t*((s+1)*t+ s) + 2); - } -} - -/** - * Easing equation function for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @param s Overshoot ammount: higher s means greater overshoot (0 produces cubic easing with no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent). - * @return The correct value. - */ -static qreal easeOutInBack(qreal t, qreal s) -{ - if (t < 0.5) return easeOutBack (2*t, s)/2; - return easeInBack(2*t - 1, s)/2 + 0.5; -} - -static qreal easeOutBounce_helper(qreal t, qreal c, qreal a) -{ - if (t == 1.0) return c; - if (t < (4/11.0)) { - return c*(7.5625*t*t); - } else if (t < (8/11.0)) { - t -= (6/11.0); - return -a * (1. - (7.5625*t*t + .75)) + c; - } else if (t < (10/11.0)) { - t -= (9/11.0); - return -a * (1. - (7.5625*t*t + .9375)) + c; - } else { - t -= (21/22.0); - return -a * (1. - (7.5625*t*t + .984375)) + c; - } -} - -/** - * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: decelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @param a Amplitude. - * @return The correct value. - */ -static qreal easeOutBounce(qreal t, qreal a) -{ - return easeOutBounce_helper(t, 1, a); -} - -/** - * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in: accelerating from zero velocity. - * - * @param t Current time (in frames or seconds). - * @param a Amplitude. - * @return The correct value. - */ -static qreal easeInBounce(qreal t, qreal a) -{ - return 1.0 - easeOutBounce_helper(1.0-t, 1.0, a); -} - - -/** - * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in/out: acceleration until halfway, then deceleration. - * - * @param t Current time (in frames or seconds). - * @param a Amplitude. - * @return The correct value. - */ -static qreal easeInOutBounce(qreal t, qreal a) -{ - if (t < 0.5) return easeInBounce (2*t, a)/2; - else return (t == 1.0) ? 1.0 : easeOutBounce (2*t - 1, a)/2 + 0.5; -} - -/** - * Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out/in: deceleration until halfway, then acceleration. - * - * @param t Current time (in frames or seconds). - * @param a Amplitude. - * @return The correct value. - */ -static qreal easeOutInBounce(qreal t, qreal a) -{ - if (t < 0.5) return easeOutBounce_helper(t*2, 0.5, a); - return 1.0 - easeOutBounce_helper (2.0-2*t, 0.5, a); -} - -static inline qreal qt_sinProgress(qreal value) -{ - return qSin((value * M_PI) - M_PI_2) / 2 + qreal(0.5); -} - -static inline qreal qt_smoothBeginEndMixFactor(qreal value) -{ - return qMin(qMax(1 - value * 2 + qreal(0.3), qreal(0.0)), qreal(1.0)); -} - -// SmoothBegin blends Smooth and Linear Interpolation. -// Progress 0 - 0.3 : Smooth only -// Progress 0.3 - ~ 0.5 : Mix of Smooth and Linear -// Progress ~ 0.5 - 1 : Linear only - -/** - * Easing function that starts growing slowly, then increases in speed. At the end of the curve the speed will be constant. - */ -static qreal easeInCurve(qreal t) -{ - const qreal sinProgress = qt_sinProgress(t); - const qreal mix = qt_smoothBeginEndMixFactor(t); - return sinProgress * mix + t * (1 - mix); -} - -/** - * Easing function that starts growing steadily, then ends slowly. The speed will be constant at the beginning of the curve. - */ -static qreal easeOutCurve(qreal t) -{ - const qreal sinProgress = qt_sinProgress(t); - const qreal mix = qt_smoothBeginEndMixFactor(1 - t); - return sinProgress * mix + t * (1 - mix); -} - -/** - * Easing function where the value grows sinusoidally. Note that the calculated end value will be 0 rather than 1. - */ -static qreal easeSineCurve(qreal t) -{ - return (qSin(((t * M_PI * 2)) - M_PI_2) + 1) / 2; -} - -/** - * Easing function where the value grows cosinusoidally. Note that the calculated start value will be 0.5 and the end value will be 0.5 - * contrary to the usual 0 to 1 easing curve. - */ -static qreal easeCosineCurve(qreal t) -{ - return (qCos(((t * M_PI * 2)) - M_PI_2) + 1) / 2; -} - diff --git a/src/3rdparty/easing/legal.qdoc b/src/3rdparty/easing/legal.qdoc deleted file mode 100644 index 25f67e1..0000000 --- a/src/3rdparty/easing/legal.qdoc +++ /dev/null @@ -1,35 +0,0 @@ -/*! -\page legal-easing.html -\title Easing Equations by Robert Penner -\ingroup animation - -\legalese -\code -Copyright (c) 2001 Robert Penner -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the author nor the names of contributors may be used - to endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -\endcode -\endlegalese -*/ diff --git a/src/corelib/animation/animation.pri b/src/corelib/animation/animation.pri deleted file mode 100644 index cb7850c..0000000 --- a/src/corelib/animation/animation.pri +++ /dev/null @@ -1,25 +0,0 @@ -# Qt core animation module - -HEADERS += \ - animation/qabstractanimation.h \ - animation/qabstractanimation_p.h \ - animation/qvariantanimation.h \ - animation/qvariantanimation_p.h \ - animation/qpropertyanimation.h \ - animation/qpropertyanimation_p.h \ - animation/qanimationgroup.h \ - animation/qanimationgroup_p.h \ - animation/qsequentialanimationgroup.h \ - animation/qsequentialanimationgroup_p.h \ - animation/qparallelanimationgroup.h \ - animation/qparallelanimationgroup_p.h \ - animation/qpauseanimation.h - -SOURCES += \ - animation/qabstractanimation.cpp \ - animation/qvariantanimation.cpp \ - animation/qpropertyanimation.cpp \ - animation/qanimationgroup.cpp \ - animation/qsequentialanimationgroup.cpp \ - animation/qparallelanimationgroup.cpp \ - animation/qpauseanimation.cpp diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp deleted file mode 100644 index 94a94d1..0000000 --- a/src/corelib/animation/qabstractanimation.cpp +++ /dev/null @@ -1,759 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QAbstractAnimation - \ingroup animation - \brief The QAbstractAnimation class is the base of all animations. - \since 4.6 - - The class defines the functions for the functionality shared by - all animations. By inheriting this class, you can create custom - animations that plug into the rest of the animation framework. - - The progress of an animation is given by its current time - (currentTime()), which is measured in milliseconds from the start - of the animation (0) to its end (duration()). The value is updated - automatically while the animation is running. It can also be set - directly with setCurrentTime(). - - At any point an animation is in one of three states: - \l{QAbstractAnimation::}{Running}, - \l{QAbstractAnimation::}{Stopped}, or - \l{QAbstractAnimation::}{Paused}--as defined by the - \l{QAbstractAnimation::}{State} enum. The current state can be - changed by calling start(), stop(), pause(), or resume(). An - animation will always reset its \l{currentTime()}{current time} - when it is started. If paused, it will continue with the same - current time when resumed. When an animation is stopped, it cannot - be resumed, but will keep its current time (until started again). - QAbstractAnimation will emit stateChanged() whenever its state - changes. - - An animation can loop any number of times by setting the loopCount - property. When an animation's current time reaches its duration(), - it will reset the current time and keep running. A loop count of 1 - (the default value) means that the animation will run one time. - Note that a duration of -1 means that the animation will run until - stopped; the current time will increase indefinitely. When the - current time equals duration() and the animation is in its - final loop, the \l{QAbstractAnimation::}{Stopped} state is - entered, and the finished() signal is emitted. - - QAbstractAnimation provides pure virtual functions used by - subclasses to track the progress of the animation: duration() and - updateCurrentTime(). The duration() function lets you report a - duration for the animation (as discussed above). The current time - is delivered by the animation framework through calls to - updateCurrentTime(). By reimplementing this function, you can - track the animation progress. Note that neither the interval - between calls nor the number of calls to this function are - defined; though, it will normally be 60 updates per second. - - By reimplementing updateState(), you can track the animation's - state changes, which is particularly useful for animations that - are not driven by time. - - \sa QVariantAnimation, QPropertyAnimation, QAnimationGroup, {The Animation Framework} -*/ - -/*! - \enum QAbstractAnimation::DeletionPolicy - - \value KeepWhenStopped The animation will not be deleted when stopped. - \value DeleteWhenStopped The animation will be automatically deleted when - stopped. -*/ - -/*! - \fn QAbstractAnimation::finished() - - QAbstractAnimation emits this signal after the animation has stopped and - has reached the end. - - This signal is emitted after stateChanged(). - - \sa stateChanged() -*/ - -/*! - \fn QAbstractAnimation::stateChanged(QAbstractAnimation::State oldState, QAbstractAnimation::State newState) - - QAbstractAnimation emits this signal whenever the state of the animation has - changed from \a oldState to \a newState. This signal is emitted after the virtual - updateState() function is called. - - \sa updateState() -*/ - -/*! - \fn QAbstractAnimation::currentLoopChanged(int currentLoop) - - QAbstractAnimation emits this signal whenever the current loop - changes. \a currentLoop is the current loop. - - \sa currentLoop(), loopCount() -*/ - -/*! - \fn QAbstractAnimation::directionChanged(QAbstractAnimation::Direction newDirection); - - QAbstractAnimation emits this signal whenever the direction has been - changed. \a newDirection is the new direction. - - \sa direction -*/ - -#ifndef QT_NO_ANIMATION - -#include "qabstractanimation.h" -#include "qanimationgroup.h" -#include - -#include "qabstractanimation_p.h" - -#include -#include -#include -#include - -#define DEFAULT_TIMER_INTERVAL 16 - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC(QThreadStorage, unifiedTimer); - -QUnifiedTimer::QUnifiedTimer() : QObject(), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL), consistentTiming(false) -{ -} - -QUnifiedTimer *QUnifiedTimer::instance() -{ - QUnifiedTimer *inst; - if (!unifiedTimer()->hasLocalData()) { - inst = new QUnifiedTimer; - unifiedTimer()->setLocalData(inst); - } else { - inst = unifiedTimer()->localData(); - } - return inst; -} - -void QUnifiedTimer::updateRecentlyStartedAnimations() -{ - if (animationsToStart.isEmpty()) - return; - - animations += animationsToStart; - updateTimer(); //we make sure we start the timer there - - animationsToStart.clear(); -} - -/* - defines the timing interval. Default is DEFAULT_TIMER_INTERVAL -*/ -void QUnifiedTimer::setTimingInterval(int interval) -{ - timingInterval = interval; - if (animationTimer.isActive()) { - //we changed the timing interval - animationTimer.start(timingInterval, this); - } -} - -/* - this allows to have a consistent timer interval at each tick from the timer - not taking the real time that passed into account. -*/ -void QUnifiedTimer::setConsistentTiming(bool b) -{ - consistentTiming = b; -} - -int QUnifiedTimer::elapsedTime() const -{ - return lastTick; -} - -void QUnifiedTimer::timerEvent(QTimerEvent *event) -{ - //this is simply the time we last received a tick - const int oldLastTick = lastTick; - if (time.isValid()) - lastTick = consistentTiming ? oldLastTick + timingInterval : time.elapsed(); - - //we transfer the waiting animations into the "really running" state - updateRecentlyStartedAnimations(); - - if (event->timerId() == startStopAnimationTimer.timerId()) { - startStopAnimationTimer.stop(); - if (animations.isEmpty()) { - animationTimer.stop(); - time = QTime(); - } else { - animationTimer.start(timingInterval, this); - lastTick = 0; - time.start(); - } - } else if (event->timerId() == animationTimer.timerId()) { - const int delta = lastTick - oldLastTick; - for (int i = 0; i < animations.count(); ++i) { - QAbstractAnimation *animation = animations.at(i); - int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime - + (animation->direction() == QAbstractAnimation::Forward ? delta : -delta); - animation->setCurrentTime(elapsed); - } - } -} - -void QUnifiedTimer::updateTimer() -{ - //we delay the call to start and stop for the animation timer so that if you - //stop and start animations in batch you don't stop/start the timer too often. - if (!startStopAnimationTimer.isActive()) - startStopAnimationTimer.start(0, this); // we delay the actual start of the animation -} - -void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation) -{ - if (animations.contains(animation) ||animationsToStart.contains(animation)) - return; - animationsToStart << animation; - updateTimer(); -} - -void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation) -{ - animations.removeAll(animation); - animationsToStart.removeAll(animation); - updateTimer(); -} - - -void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) -{ - Q_Q(QAbstractAnimation); - if (state == newState) - return; - - QAbstractAnimation::State oldState = state; - int oldCurrentTime = currentTime; - int oldCurrentLoop = currentLoop; - QAbstractAnimation::Direction oldDirection = direction; - - state = newState; - - QPointer guard(q); - - guard->updateState(oldState, newState); - - //this is to be safe if updateState changes the state - if (state == oldState) - return; - - // Notify state change - if (guard) - emit guard->stateChanged(oldState, newState); - - // Enter running state. - switch (state) - { - case QAbstractAnimation::Paused: - case QAbstractAnimation::Running: - { - // Rewind - if (oldState == QAbstractAnimation::Stopped) { - if (guard) { - if (direction == QAbstractAnimation::Forward) - q->setCurrentTime(0); - else - q->setCurrentTime(loopCount == -1 ? q->duration() : q->totalDuration()); - } - - // Check if the setCurrentTime() function called stop(). - // This can happen for a 0-duration animation - if (state == QAbstractAnimation::Stopped) - return; - } - - // Register timer if our parent is not running. - if (state == QAbstractAnimation::Running && guard) { - if (!group || group->state() == QAbstractAnimation::Stopped) { - QUnifiedTimer::instance()->registerAnimation(q); - } - } else { - //new state is paused - QUnifiedTimer::instance()->unregisterAnimation(q); - } - } - break; - case QAbstractAnimation::Stopped: - // Leave running state. - int dura = q->duration(); - if (deleteWhenStopped && guard) - q->deleteLater(); - - QUnifiedTimer::instance()->unregisterAnimation(q); - - if (dura == -1 || loopCount < 0 - || (oldDirection == QAbstractAnimation::Forward && (oldCurrentTime * (oldCurrentLoop + 1)) == (dura * loopCount)) - || (oldDirection == QAbstractAnimation::Backward && oldCurrentTime == 0)) { - if (guard) - emit q->finished(); - } - break; - } - -} - -/*! - Constructs the QAbstractAnimation base class, and passes \a parent to - QObject's constructor. - - \sa QVariantAnimation, QAnimationGroup -*/ -QAbstractAnimation::QAbstractAnimation(QObject *parent) - : QObject(*new QAbstractAnimationPrivate, 0) -{ - // Allow auto-add on reparent - setParent(parent); -} - -/*! - \internal -*/ -QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent) - : QObject(dd, 0) -{ - // Allow auto-add on reparent - setParent(parent); -} - -/*! - Stops the animation if it's running, then destroys the - QAbstractAnimation. If the animation is part of a QAnimationGroup, it is - automatically removed before it's destroyed. -*/ -QAbstractAnimation::~QAbstractAnimation() -{ - Q_D(QAbstractAnimation); - //we can't call stop here. Otherwise we get pure virtual calls - if (d->state != Stopped) { - QAbstractAnimation::State oldState = d->state; - d->state = Stopped; - emit stateChanged(oldState, d->state); - QUnifiedTimer::instance()->unregisterAnimation(this); - } -} - -/*! - \property QAbstractAnimation::state - \brief state of the animation. - - This property describes the current state of the animation. When the - animation state changes, QAbstractAnimation emits the stateChanged() - signal. -*/ -QAbstractAnimation::State QAbstractAnimation::state() const -{ - Q_D(const QAbstractAnimation); - return d->state; -} - -/*! - If this animation is part of a QAnimationGroup, this function returns a - pointer to the group; otherwise, it returns 0. - - \sa QAnimationGroup::addAnimation() -*/ -QAnimationGroup *QAbstractAnimation::group() const -{ - Q_D(const QAbstractAnimation); - return d->group; -} - -/*! - \enum QAbstractAnimation::State - - This enum describes the state of the animation. - - \value Stopped The animation is not running. This is the initial state - of QAbstractAnimation, and the state QAbstractAnimation reenters when finished. The current - time remain unchanged until either setCurrentTime() is - called, or the animation is started by calling start(). - - \value Paused The animation is paused (i.e., temporarily - suspended). Calling resume() will resume animation activity. - - \value Running The animation is running. While control is in the event - loop, QAbstractAnimation will update its current time at regular intervals, - calling updateCurrentTime() when appropriate. - - \sa state(), stateChanged() -*/ - -/*! - \enum QAbstractAnimation::Direction - - This enum describes the direction of the animation when in \l Running state. - - \value Forward The current time of the animation increases with time (i.e., - moves from 0 and towards the end / duration). - - \value Backward The current time of the animation decreases with time (i.e., - moves from the end / duration and towards 0). - - \sa direction -*/ - -/*! - \property QAbstractAnimation::direction - \brief the direction of the animation when it is in \l Running - state. - - This direction indicates whether the time moves from 0 towards the - animation duration, or from the value of the duration and towards 0 after - start() has been called. - - By default, this property is set to \l Forward. -*/ -QAbstractAnimation::Direction QAbstractAnimation::direction() const -{ - Q_D(const QAbstractAnimation); - return d->direction; -} -void QAbstractAnimation::setDirection(Direction direction) -{ - Q_D(QAbstractAnimation); - if (d->direction == direction) - return; - - d->direction = direction; - if (state() == Stopped) { - if (direction == Backward) { - d->currentTime = duration(); - d->currentLoop = d->loopCount - 1; - } else { - d->currentTime = 0; - d->currentLoop = 0; - } - } - updateDirection(direction); - emit directionChanged(direction); -} - -/*! - \property QAbstractAnimation::duration - \brief the duration of the animation. - - If the duration is -1, it means that the duration is undefined. - In this case, loopCount is ignored. -*/ - -/*! - \property QAbstractAnimation::loopCount - \brief the loop count of the animation - - This property describes the loop count of the animation as an integer. - By default this value is 1, indicating that the animation - should run once only, and then stop. By changing it you can let the - animation loop several times. With a value of 0, the animation will not - run at all, and with a value of -1, the animation will loop forever - until stopped. - It is not supported to have loop on an animation that has an undefined - duration. It will only run once. -*/ -int QAbstractAnimation::loopCount() const -{ - Q_D(const QAbstractAnimation); - return d->loopCount; -} -void QAbstractAnimation::setLoopCount(int loopCount) -{ - Q_D(QAbstractAnimation); - d->loopCount = loopCount; -} - -/*! - \property QAbstractAnimation::currentLoop - \brief the current loop of the animation - - This property describes the current loop of the animation. By default, - the animation's loop count is 1, and so the current loop will - always be 0. If the loop count is 2 and the animation runs past its - duration, it will automatically rewind and restart at current time 0, and - current loop 1, and so on. - - When the current loop changes, QAbstractAnimation emits the - currentLoopChanged() signal. -*/ -int QAbstractAnimation::currentLoop() const -{ - Q_D(const QAbstractAnimation); - return d->currentLoop; -} - -/*! - \fn virtual int QAbstractAnimation::duration() const = 0 - - This pure virtual function returns the duration of the animation, and - defines for how long QAbstractAnimation should update the current - time. This duration is local, and does not include the loop count. - - A return value of -1 indicates that the animation has no defined duration; - the animation should run forever until stopped. This is useful for - animations that are not time driven, or where you cannot easily predict - its duration (e.g., event driven audio playback in a game). - - If the animation is a parallel QAnimationGroup, the duration will be the longest - duration of all its animations. If the animation is a sequential QAnimationGroup, - the duration will be the sum of the duration of all its animations. - \sa loopCount -*/ - -/*! - Returns the total and effective duration of the animation, including the - loop count. - - \sa duration(), currentTime -*/ -int QAbstractAnimation::totalDuration() const -{ - Q_D(const QAbstractAnimation); - if (d->loopCount < 0) - return -1; - int dura = duration(); - if (dura == -1) - return -1; - return dura * d->loopCount; -} - -/*! - \property QAbstractAnimation::currentTime - \brief the current time and progress of the animation - - This property describes the animation's current time. You can change the - current time by calling setCurrentTime, or you can call start() and let - the animation run, setting the current time automatically as the animation - progresses. - - The animation's current time starts at 0, and ends at duration(). If the - animation's loopCount is larger than 1, the current time will rewind and - start at 0 again for the consecutive loops. If the animation has a pause. - currentTime will also include the duration of the pause. - - \sa loopCount - */ -int QAbstractAnimation::currentTime() const -{ - Q_D(const QAbstractAnimation); - return d->currentTime; -} -void QAbstractAnimation::setCurrentTime(int msecs) -{ - Q_D(QAbstractAnimation); - msecs = qMax(msecs, 0); - - // Calculate new time and loop. - int dura = duration(); - int totalDura = (d->loopCount < 0 || dura == -1) ? -1 : dura * d->loopCount; - if (totalDura != -1) - msecs = qMin(totalDura, msecs); - d->totalCurrentTime = msecs; - - // Update new values. - int oldLoop = d->currentLoop; - d->currentLoop = ((dura <= 0) ? 0 : (msecs / dura)); - if (d->currentLoop == d->loopCount) { - //we're at the end - d->currentTime = qMax(0, dura); - d->currentLoop = qMax(0, d->loopCount - 1); - } else { - if (d->direction == Forward) { - d->currentTime = (dura <= 0) ? msecs : (msecs % dura); - } else { - d->currentTime = (dura <= 0) ? msecs : ((msecs - 1) % dura) + 1; - if (d->currentTime == dura) - --d->currentLoop; - } - } - - updateCurrentTime(msecs); - if (d->currentLoop != oldLoop) - emit currentLoopChanged(d->currentLoop); - - // All animations are responsible for stopping the animation when their - // own end state is reached; in this case the animation is time driven, - // and has reached the end. - if ((d->direction == Forward && d->totalCurrentTime == totalDura) - || (d->direction == Backward && d->totalCurrentTime == 0)) { - stop(); - } -} - -/*! - Starts the animation. The \a policy argument says whether or not the - animation should be deleted when it's done. When the animation starts, the - stateChanged() signal is emitted, and state() returns Running. When control - reaches the event loop, the animation will run by itself, periodically - calling updateCurrentTime() as the animation progresses. - - If the animation is currently stopped or has already reached the end, - calling start() will rewind the animation and start again from the beginning. - When the animation reaches the end, the animation will either stop, or - if the loop level is more than 1, it will rewind and continue from the beginning. - - If the animation is already running, this function does nothing. - - \sa stop(), state() -*/ -void QAbstractAnimation::start(DeletionPolicy policy) -{ - Q_D(QAbstractAnimation); - if (d->state == Running) - return; - d->setState(Running); - d->deleteWhenStopped = policy; -} - -/*! - Stops the animation. When the animation is stopped, it emits the stateChanged() - signal, and state() returns Stopped. The current time is not changed. - - If the animation stops by itself after reaching the end (i.e., - currentTime() == duration() and currentLoop() > loopCount() - 1), the - finished() signal is emitted. - - \sa start(), state() - */ -void QAbstractAnimation::stop() -{ - Q_D(QAbstractAnimation); - - d->setState(Stopped); -} - -/*! - Pauses the animation. When the animation is paused, state() returns Paused. - The currenttime will remain unchanged until resume() or start() is called. - If you want to continue from the current time, call resume(). - - - \sa start(), state(), resume() - */ -void QAbstractAnimation::pause() -{ - Q_D(QAbstractAnimation); - if (d->state == Stopped) { - qWarning("QAbstractAnimation::pause: Cannot pause a stopped animation"); - return; - } - - d->setState(Paused); -} - -/*! - Resumes the animation after it was paused. When the animation is resumed, - it emits the resumed() and stateChanged() signals. The currenttime is not - changed. - - \sa start(), pause(), state() - */ -void QAbstractAnimation::resume() -{ - Q_D(QAbstractAnimation); - if (d->state != Paused) { - qWarning("QAbstractAnimation::resume: " - "Cannot resume an animation that is not paused"); - return; - } - - d->setState(Running); -} - -/*! - \reimp -*/ -bool QAbstractAnimation::event(QEvent *event) -{ - return QObject::event(event); -} - -/*! - \fn virtual void QAbstractAnimation::updateCurrentTime(int msecs) = 0; - - This pure virtual function is called every time the animation's current - time changes. The \a msecs argument is the current time. - - \sa updateState() -*/ - -/*! - This virtual function is called by QAbstractAnimation when the state - of the animation is changed from \a oldState to \a newState. - - \sa start(), stop(), pause(), resume() -*/ -void QAbstractAnimation::updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) -{ - Q_UNUSED(oldState); - Q_UNUSED(newState); -} - -/*! - This virtual function is called by QAbstractAnimation when the direction - of the animation is changed. The \a direction argument is the new direction. - - \sa setDirection(), direction() -*/ -void QAbstractAnimation::updateDirection(QAbstractAnimation::Direction direction) -{ - Q_UNUSED(direction); -} - - -QT_END_NAMESPACE - -#include "moc_qabstractanimation.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h deleted file mode 100644 index d6d50dc..0000000 --- a/src/corelib/animation/qabstractanimation.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QABSTRACTANIMATION_H -#define QABSTRACTANIMATION_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -#ifndef QT_NO_ANIMATION - -class QAnimationGroup; -class QSequentialAnimationGroup; - -class QAbstractAnimationPrivate; -class Q_CORE_EXPORT QAbstractAnimation : public QObject -{ - Q_OBJECT - Q_PROPERTY(State state READ state NOTIFY stateChanged) - Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount) - Q_PROPERTY(int currentTime READ currentTime WRITE setCurrentTime) - Q_PROPERTY(int currentLoop READ currentLoop NOTIFY currentLoopChanged) - Q_PROPERTY(Direction direction READ direction WRITE setDirection NOTIFY directionChanged) - Q_PROPERTY(int duration READ duration) - -public: - enum Direction { - Forward, - Backward - }; - - enum State { - Stopped, - Paused, - Running - }; - - enum DeletionPolicy { - KeepWhenStopped = 0, - DeleteWhenStopped - }; - - QAbstractAnimation(QObject *parent = 0); - virtual ~QAbstractAnimation(); - - State state() const; - - QAnimationGroup *group() const; - - Direction direction() const; - void setDirection(Direction direction); - - int loopCount() const; - void setLoopCount(int loopCount); - int currentLoop() const; - - virtual int duration() const = 0; - int totalDuration() const; - - int currentTime() const; - -Q_SIGNALS: - void finished(); - void stateChanged(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - void currentLoopChanged(int currentLoop); - void directionChanged(QAbstractAnimation::Direction); - -public Q_SLOTS: - void start(QAbstractAnimation::DeletionPolicy policy = KeepWhenStopped); - void pause(); - void resume(); - void stop(); - void setCurrentTime(int msecs); - -protected: - QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = 0); - bool event(QEvent *event); - - virtual void updateCurrentTime(int msecs) = 0; - virtual void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - virtual void updateDirection(QAbstractAnimation::Direction direction); - -private: - Q_DISABLE_COPY(QAbstractAnimation) - Q_DECLARE_PRIVATE(QAbstractAnimation) -}; - -#endif //QT_NO_ANIMATION - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QABSTRACTANIMATION_H diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h deleted file mode 100644 index e64554c..0000000 --- a/src/corelib/animation/qabstractanimation_p.h +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QABSTRACTANIMATION_P_H -#define QABSTRACTANIMATION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of QIODevice. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QAnimationGroup; -class QAbstractAnimation; -class QAbstractAnimationPrivate : public QObjectPrivate -{ -public: - QAbstractAnimationPrivate() - : state(QAbstractAnimation::Stopped), - direction(QAbstractAnimation::Forward), - deleteWhenStopped(false), - totalCurrentTime(0), - currentTime(0), - loopCount(1), - currentLoop(0), - group(0) - { - } - - virtual ~QAbstractAnimationPrivate() {} - - static QAbstractAnimationPrivate *get(QAbstractAnimation *q) - { - return q->d_func(); - } - - QAbstractAnimation::State state; - QAbstractAnimation::Direction direction; - bool deleteWhenStopped; - void setState(QAbstractAnimation::State state); - - int totalCurrentTime; - int currentTime; - int loopCount; - int currentLoop; - - QAnimationGroup *group; - -private: - Q_DECLARE_PUBLIC(QAbstractAnimation) -}; - - -class Q_CORE_EXPORT QUnifiedTimer : public QObject -{ -private: - QUnifiedTimer(); - -public: - static QUnifiedTimer *instance(); - - void registerAnimation(QAbstractAnimation *animation); - void unregisterAnimation(QAbstractAnimation *animation); - - void setTimingInterval(int interval); - void setConsistentTiming(bool consistent); - - int elapsedTime() const; - -protected: - void timerEvent(QTimerEvent *); - void updateTimer(); - -private: - void updateRecentlyStartedAnimations(); - - QBasicTimer animationTimer, startStopAnimationTimer; - QTime time; - int lastTick; - int timingInterval; - bool consistentTiming; - QList animations, animationsToStart; -}; - -QT_END_NAMESPACE -#endif diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp deleted file mode 100644 index ed06eff..0000000 --- a/src/corelib/animation/qanimationgroup.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QAnimationGroup - \brief The QAnimationGroup class is an abstract base class for groups of animations. - \since 4.6 - \ingroup animation - - An animation group is a container for animations (subclasses of - QAbstractAnimation). A group is usually responsible for managing - the \l{QAbstractAnimation::State}{state} of its animations, i.e., - it decides when to start, stop, resume, and pause them. Currently, - Qt provides two such groups: QParallelAnimationGroup and - QSequentialAnimationGroup. Look up their class descriptions for - details. - - Since QAnimationGroup inherits from QAbstractAnimation, you can - combine groups, and easily construct complex animation graphs. - You can query QAbstractAnimation for the group it belongs to - (using the \l{QAbstractAnimation::}{group()} function). - - To start a top-level animation group, you simply use the - \l{QAbstractAnimation::}{start()} function from - QAbstractAnimation. By a top-level animation group, we think of a - group that itself is not contained within another group. Starting - sub groups directly is not supported, and may lead to unexpected - behavior. - - \omit OK, we'll put in a snippet on this here \endomit - - QAnimationGroup provides methods for adding and retrieving - animations. Besides that, you can remove animations by calling - remove(), and clear the animation group by calling - clearAnimations(). You may keep track of changes in the group's - animations by listening to QEvent::ChildAdded and - QEvent::ChildRemoved events. - - \omit OK, let's find a snippet here as well. \endomit - - QAnimationGroup takes ownership of the animations it manages, and - ensures that they are deleted when the animation group is deleted. - - You can also use a \l{The State Machine Framework}{state machine} - to create complex animations. The framework provides a special - state, QAnimationState, that plays an animation upon entry and - transitions to a new state when the animation has finished - playing. This technique can also be combined with using animation - groups. - - \sa QAbstractAnimation, QVariantAnimation, {The Animation Framework} -*/ - -#ifndef QT_NO_ANIMATION - -#include "qanimationgroup.h" -#include -#include -#include "qanimationgroup_p.h" - -QT_BEGIN_NAMESPACE - - -/*! - Constructs a QAnimationGroup. - \a parent is passed to QObject's constructor. -*/ -QAnimationGroup::QAnimationGroup(QObject *parent) - : QAbstractAnimation(*new QAnimationGroupPrivate, parent) -{ -} - -/*! - \internal -*/ -QAnimationGroup::QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent) - : QAbstractAnimation(dd, parent) -{ -} - -/*! - Destroys the animation group. It will also destroy all its animations. -*/ -QAnimationGroup::~QAnimationGroup() -{ -} - -/*! - Returns a pointer to the animation at \a index in this group. This - function is useful when you need access to a particular animation. \a - index is between 0 and animationCount() - 1. - - \sa animationCount(), indexOfAnimation() -*/ -QAbstractAnimation *QAnimationGroup::animationAt(int index) const -{ - Q_D(const QAnimationGroup); - - if (index < 0 || index >= d->animations.size()) { - qWarning("QAnimationGroup::animationAt: index is out of bounds"); - return 0; - } - - return d->animations.at(index); -} - - -/*! - Returns the number of animations managed by this group. - - \sa indexOfAnimation(), addAnimation(), animationAt() -*/ -int QAnimationGroup::animationCount() const -{ - Q_D(const QAnimationGroup); - return d->animations.size(); -} - -/*! - Returns the index of \a animation. The returned index can be passed - to the other functions that take an index as an argument. - - \sa insertAnimationAt(), animationAt(), takeAnimationAt() -*/ -int QAnimationGroup::indexOfAnimation(QAbstractAnimation *animation) const -{ - Q_D(const QAnimationGroup); - return d->animations.indexOf(animation); -} - -/*! - Adds \a animation to this group. This will call insertAnimationAt with - index equals to animationCount(). - - \note The group takes ownership of the animation. - - \sa removeAnimation() -*/ -void QAnimationGroup::addAnimation(QAbstractAnimation *animation) -{ - Q_D(QAnimationGroup); - insertAnimationAt(d->animations.count(), animation); -} - -/*! - Inserts \a animation into this animation group at \a index. - If \a index is 0 the animation is inserted at the beginning. - If \a index is animationCount(), the animation is inserted at the end. - - \note The group takes ownership of the animation. - - \sa takeAnimationAt(), addAnimation(), indexOfAnimation(), removeAnimation() -*/ -void QAnimationGroup::insertAnimationAt(int index, QAbstractAnimation *animation) -{ - Q_D(QAnimationGroup); - - if (index < 0 || index > d->animations.size()) { - qWarning("QAnimationGroup::insertAnimationAt: index is out of bounds"); - return; - } - - if (QAnimationGroup *oldGroup = animation->group()) - oldGroup->removeAnimation(animation); - - d->animations.insert(index, animation); - QAbstractAnimationPrivate::get(animation)->group = this; - // this will make sure that ChildAdded event is sent to 'this' - animation->setParent(this); - d->animationInsertedAt(index); -} - -/*! - Removes \a animation from this group. The ownership of \a animation is - transferred to the caller. - - \sa takeAnimationAt(), insertAnimationAt(), addAnimation() -*/ -void QAnimationGroup::removeAnimation(QAbstractAnimation *animation) -{ - Q_D(QAnimationGroup); - - if (!animation) { - qWarning("QAnimationGroup::remove: cannot remove null animation"); - return; - } - int index = d->animations.indexOf(animation); - if (index == -1) { - qWarning("QAnimationGroup::remove: animation is not part of this group"); - return; - } - - takeAnimationAt(index); -} - -/*! - Returns the animation at \a index and removes it from the animation group. - - \note The ownership of the animation is transferred to the caller. - - \sa removeAnimation(), addAnimation(), insertAnimation(), indexOfAnimation() -*/ -QAbstractAnimation *QAnimationGroup::takeAnimationAt(int index) -{ - Q_D(QAnimationGroup); - if (index < 0 || index >= d->animations.size()) { - qWarning("QAnimationGroup::takeAnimationAt: no animation at index %d", index); - return 0; - } - QAbstractAnimation *animation = d->animations.at(index); - QAbstractAnimationPrivate::get(animation)->group = 0; - // ### removing from list before doing setParent to avoid inifinite recursion - // in ChildRemoved event - d->animations.removeAt(index); - animation->setParent(0); - d->animationRemovedAt(index); - return animation; -} - -/*! - Removes and deletes all animations in this animation group, and resets the current - time to 0. - - \sa addAnimation(), removeAnimation() -*/ -void QAnimationGroup::clearAnimations() -{ - Q_D(QAnimationGroup); - qDeleteAll(d->animations); -} - -/*! - \reimp -*/ -bool QAnimationGroup::event(QEvent *event) -{ - Q_D(QAnimationGroup); - if (event->type() == QEvent::ChildAdded) { - QChildEvent *childEvent = static_cast(event); - if (QAbstractAnimation *a = qobject_cast(childEvent->child())) { - if (a->group() != this) - addAnimation(a); - } - } else if (event->type() == QEvent::ChildRemoved) { - QChildEvent *childEvent = static_cast(event); - QAbstractAnimation *a = static_cast(childEvent->child()); - // You can only rely on the child being a QObject because in the QEvent::ChildRemoved - // case it might be called from the destructor. - int index = d->animations.indexOf(a); - if (index != -1) - takeAnimationAt(index); - } - return QAbstractAnimation::event(event); -} - - -void QAnimationGroupPrivate::animationRemovedAt(int index) -{ - Q_Q(QAnimationGroup); - Q_UNUSED(index); - if (animations.isEmpty()) { - currentTime = 0; - q->stop(); - } -} - -QT_END_NAMESPACE - -#include "moc_qanimationgroup.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qanimationgroup.h b/src/corelib/animation/qanimationgroup.h deleted file mode 100644 index 263bc38..0000000 --- a/src/corelib/animation/qanimationgroup.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANIMATIONGROUP_H -#define QANIMATIONGROUP_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -#ifndef QT_NO_ANIMATION - -class QAnimationGroupPrivate; -class Q_CORE_EXPORT QAnimationGroup : public QAbstractAnimation -{ - Q_OBJECT - -public: - QAnimationGroup(QObject *parent = 0); - ~QAnimationGroup(); - - QAbstractAnimation *animationAt(int index) const; - int animationCount() const; - int indexOfAnimation(QAbstractAnimation *animation) const; - void addAnimation(QAbstractAnimation *animation); - void insertAnimationAt(int index, QAbstractAnimation *animation); - void removeAnimation(QAbstractAnimation *animation); - QAbstractAnimation *takeAnimationAt(int index); - void clearAnimations(); - -protected: - QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent); - bool event(QEvent *event); - -private: - Q_DISABLE_COPY(QAnimationGroup) - Q_DECLARE_PRIVATE(QAnimationGroup) -}; - -#endif //QT_NO_ANIMATION - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif //QANIMATIONGROUP_H diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h deleted file mode 100644 index a7bd0fa..0000000 --- a/src/corelib/animation/qanimationgroup_p.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANIMATIONGROUP_P_H -#define QANIMATIONGROUP_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of QIODevice. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qanimationgroup.h" - -#include - -#include "qabstractanimation_p.h" - -QT_BEGIN_NAMESPACE - -class QAnimationGroupPrivate : public QAbstractAnimationPrivate -{ - Q_DECLARE_PUBLIC(QAnimationGroup) -public: - QAnimationGroupPrivate() - { } - - virtual void animationInsertedAt(int index) { Q_UNUSED(index) }; - virtual void animationRemovedAt(int index); - - QList animations; -}; - -QT_END_NAMESPACE - -#endif //QANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp deleted file mode 100644 index 13f6073..0000000 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QParallelAnimationGroup - \brief The QParallelAnimationGroup class provides a parallel group of animations. - \since 4.6 - \ingroup animation - - QParallelAnimationGroup--a \l{QAnimationGroup}{container for - animations}--starts all its animations when it is - \l{QAbstractAnimation::start()}{started} itself, i.e., runs all - animations in parallel. The animation group finishes when the - longest lasting animation has finished. - - You can treat QParallelAnimation as any other QAbstractAnimation, - e.g., pause, resume, or add it to other animation groups. - - \code - QParallelAnimationGroup *group = new QParallelAnimationGroup; - group->addAnimation(anim1); - group->addAnimation(anim2); - - group->start(); - \endcode - - In this example, \c anim1 and \c anim2 are two - \l{QPropertyAnimation}s that have already been set up. - - \sa QAnimationGroup, QPropertyAnimation, {The Animation Framework} -*/ - -#ifndef QT_NO_ANIMATION - -#include "qparallelanimationgroup.h" -#include "qparallelanimationgroup_p.h" -//#define QANIMATION_DEBUG -QT_BEGIN_NAMESPACE - -/*! - Constructs a QParallelAnimationGroup. - \a parent is passed to QObject's constructor. -*/ -QParallelAnimationGroup::QParallelAnimationGroup(QObject *parent) - : QAnimationGroup(*new QParallelAnimationGroupPrivate, parent) -{ -} - -/*! - \internal -*/ -QParallelAnimationGroup::QParallelAnimationGroup(QParallelAnimationGroupPrivate &dd, - QObject *parent) - : QAnimationGroup(dd, parent) -{ -} - -/*! - Destroys the animation group. It will also destroy all its animations. -*/ -QParallelAnimationGroup::~QParallelAnimationGroup() -{ -} - -/*! - \reimp -*/ -int QParallelAnimationGroup::duration() const -{ - Q_D(const QParallelAnimationGroup); - int ret = 0; - - for (int i = 0; i < d->animations.size(); ++i) { - QAbstractAnimation *animation = d->animations.at(i); - const int currentDuration = animation->totalDuration(); - if (currentDuration == -1) - return -1; // Undetermined length - - ret = qMax(ret, currentDuration); - } - - return ret; -} - -/*! - \reimp -*/ -void QParallelAnimationGroup::updateCurrentTime(int) -{ - Q_D(QParallelAnimationGroup); - if (d->animations.isEmpty()) - return; - - if (d->currentLoop > d->lastLoop) { - // simulate completion of the loop - int dura = duration(); - if (dura > 0) { - foreach (QAbstractAnimation *animation, d->animations) { - animation->setCurrentTime(dura); // will stop - } - } - } else if (d->currentLoop < d->lastLoop) { - // simulate completion of the loop seeking backwards - foreach (QAbstractAnimation *animation, d->animations) { - animation->setCurrentTime(0); - animation->stop(); - } - } - - bool timeFwd = ((d->currentLoop == d->lastLoop && d->currentTime >= d->lastCurrentTime) - || d->currentLoop > d->lastLoop); -#ifdef QANIMATION_DEBUG - qDebug("QParallellAnimationGroup %5d: setCurrentTime(%d), loop:%d, last:%d, timeFwd:%d, lastcurrent:%d, %d", - __LINE__, d->currentTime, d->currentLoop, d->lastLoop, timeFwd, d->lastCurrentTime, state()); -#endif - // finally move into the actual time of the current loop - foreach (QAbstractAnimation *animation, d->animations) { - const int dura = animation->totalDuration(); - if (dura == -1 && d->isUncontrolledAnimationFinished(animation)) - continue; - if (dura == -1 || (d->currentTime <= dura && dura != 0) - || (dura == 0 && d->currentLoop != d->lastLoop)) { - switch (state()) { - case Running: - animation->start(); - break; - case Paused: - animation->pause(); - break; - case Stopped: - default: - break; - } - } - - if (dura <= 0) { - if (dura == -1) - animation->setCurrentTime(d->currentTime); - continue; - } - - if ((timeFwd && d->lastCurrentTime <= dura) - || (!timeFwd && d->currentTime <= dura)) - animation->setCurrentTime(d->currentTime); - if (d->currentTime > dura) - animation->stop(); - } - d->lastLoop = d->currentLoop; - d->lastCurrentTime = d->currentTime; -} - -/*! - \reimp -*/ -void QParallelAnimationGroup::updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) -{ - Q_D(QParallelAnimationGroup); - QAnimationGroup::updateState(oldState, newState); - - switch (newState) { - case Stopped: - foreach (QAbstractAnimation *animation, d->animations) - animation->stop(); - d->disconnectUncontrolledAnimations(); - break; - case Paused: - foreach (QAbstractAnimation *animation, d->animations) - animation->pause(); - break; - case Running: - d->connectUncontrolledAnimations(); - foreach (QAbstractAnimation *animation, d->animations) { - animation->stop(); - animation->setDirection(d->direction); - animation->start(); - } - break; - } -} - -void QParallelAnimationGroupPrivate::_q_uncontrolledAnimationFinished() -{ - Q_Q(QParallelAnimationGroup); - - QAbstractAnimation *animation = qobject_cast(q->sender()); - Q_ASSERT(animation); - - int uncontrolledRunningCount = 0; - if (animation->duration() == -1 || animation->loopCount() < 0) { - QHash::iterator it = uncontrolledFinishTime.begin(); - while (it != uncontrolledFinishTime.end()) { - if (it.key() == animation) { - *it = animation->currentTime(); - } - if (it.value() == -1) - ++uncontrolledRunningCount; - ++it; - } - } - - if (uncontrolledRunningCount > 0) - return; - - int maxDuration = 0; - foreach (QAbstractAnimation *a, animations) - maxDuration = qMax(maxDuration, a->totalDuration()); - - if (currentTime >= maxDuration) - q->stop(); -} - -void QParallelAnimationGroupPrivate::disconnectUncontrolledAnimations() -{ - Q_Q(QParallelAnimationGroup); - - QHash::iterator it = uncontrolledFinishTime.begin(); - while (it != uncontrolledFinishTime.end()) { - QObject::disconnect(it.key(), SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); - ++it; - } - - uncontrolledFinishTime.clear(); -} - -void QParallelAnimationGroupPrivate::connectUncontrolledAnimations() -{ - Q_Q(QParallelAnimationGroup); - - foreach (QAbstractAnimation *animation, animations) { - if (animation->duration() == -1 || animation->loopCount() < 0) { - uncontrolledFinishTime[animation] = -1; - QObject::connect(animation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); - } - } -} - -bool QParallelAnimationGroupPrivate::isUncontrolledAnimationFinished(QAbstractAnimation *anim) const -{ - return uncontrolledFinishTime.value(anim, -1) >= 0; -} - -/*! - \reimp -*/ -void QParallelAnimationGroup::updateDirection(QAbstractAnimation::Direction direction) -{ - Q_D(QParallelAnimationGroup); - //we need to update the direction of the current animation - if (state() != Stopped) { - foreach(QAbstractAnimation *anim, d->animations) { - anim->setDirection(direction); - } - } else { - if (direction == Forward) { - d->lastLoop = 0; - d->lastCurrentTime = 0; - } else { - // Looping backwards with loopCount == -1 does not really work well... - d->lastLoop = (d->loopCount == -1 ? 0 : d->loopCount - 1); - d->lastCurrentTime = duration(); - } - } -} - -/*! - \reimp -*/ -bool QParallelAnimationGroup::event(QEvent *event) -{ - return QAnimationGroup::event(event); -} - -QT_END_NAMESPACE - -#include "moc_qparallelanimationgroup.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qparallelanimationgroup.h b/src/corelib/animation/qparallelanimationgroup.h deleted file mode 100644 index 57a8146..0000000 --- a/src/corelib/animation/qparallelanimationgroup.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPARALLELANIMATIONGROUP_H -#define QPARALLELANIMATIONGROUP_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -#ifndef QT_NO_ANIMATION - -class QParallelAnimationGroupPrivate; -class Q_CORE_EXPORT QParallelAnimationGroup : public QAnimationGroup -{ - Q_OBJECT - -public: - QParallelAnimationGroup(QObject *parent = 0); - ~QParallelAnimationGroup(); - - int duration() const; - -protected: - QParallelAnimationGroup(QParallelAnimationGroupPrivate &dd, QObject *parent); - bool event(QEvent *event); - - void updateCurrentTime(int msecs); - void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - void updateDirection(QAbstractAnimation::Direction direction); - -private: - Q_DISABLE_COPY(QParallelAnimationGroup) - Q_DECLARE_PRIVATE(QParallelAnimationGroup) - Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished()) -}; - -#endif //QT_NO_ANIMATION - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QPARALLELANIMATIONGROUP diff --git a/src/corelib/animation/qparallelanimationgroup_p.h b/src/corelib/animation/qparallelanimationgroup_p.h deleted file mode 100644 index f36d972..0000000 --- a/src/corelib/animation/qparallelanimationgroup_p.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPARALLELANIMATIONGROUP_P_H -#define QPARALLELANIMATIONGROUP_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of QIODevice. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qparallelanimationgroup.h" -#include "qanimationgroup_p.h" -#include - -QT_BEGIN_NAMESPACE - -class QParallelAnimationGroupPrivate : public QAnimationGroupPrivate -{ - Q_DECLARE_PUBLIC(QParallelAnimationGroup) -public: - QParallelAnimationGroupPrivate() - : lastLoop(0), lastCurrentTime(0) - { - } - - QHash uncontrolledFinishTime; - int lastLoop; - int lastCurrentTime; - - bool isUncontrolledAnimationFinished(QAbstractAnimation *anim) const; - void connectUncontrolledAnimations(); - void disconnectUncontrolledAnimations(); - - // private slot - void _q_uncontrolledAnimationFinished(); -}; - -QT_END_NAMESPACE - -#endif //QPARALLELANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qpauseanimation.cpp b/src/corelib/animation/qpauseanimation.cpp deleted file mode 100644 index b175f0c..0000000 --- a/src/corelib/animation/qpauseanimation.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QPauseAnimation - \brief The QPauseAnimation class provides a pause for QSequentialAnimationGroup. - \since 4.6 - \ingroup animation - - If you wish to introduce a delay between animations in a - QSequentialAnimationGroup, you can insert a QPauseAnimation. This - class does not animate anything, but does not - \l{QAbstractAnimation::finished()}{finish} before a specified - number of milliseconds have elapsed from when it was started. You - specify the duration of the pause in the constructor. It can also - be set directly with setDuration(). - - It is not necessary to construct a QPauseAnimation yourself. - QSequentialAnimationGroup provides the convenience functions - \l{QSequentialAnimationGroup::}{addPause()} and - \l{QSequentialAnimationGroup::}{insertPauseAt()}. These functions - simply take the number of milliseconds the pause should last. - - \sa QSequentialAnimationGroup -*/ - -#ifndef QT_NO_ANIMATION - -#include "qpauseanimation.h" -#include "qabstractanimation_p.h" - - -QT_BEGIN_NAMESPACE - -class QPauseAnimationPrivate : public QAbstractAnimationPrivate -{ -public: - QPauseAnimationPrivate() : QAbstractAnimationPrivate(), duration(0) - { - } - - int duration; -}; - -/*! - Constructs a QPauseAnimation. - \a parent is passed to QObject's constructor. - The default duration is 0. -*/ - -QPauseAnimation::QPauseAnimation(QObject *parent) : QAbstractAnimation(*new QPauseAnimationPrivate, parent) -{ -} - -/*! - Constructs a QPauseAnimation. - \a msecs is the duration of the pause. - \a parent is passed to QObject's constructor. -*/ - -QPauseAnimation::QPauseAnimation(int msecs, QObject *parent) : QAbstractAnimation(*new QPauseAnimationPrivate, parent) -{ - setDuration(msecs); -} - -/*! - Destroys the pause animation. -*/ -QPauseAnimation::~QPauseAnimation() -{ -} - -/*! - \property QPauseAnimation::duration - \brief the duration of the pause. - - The duration of the pause. The duration should not be negative. -*/ -int QPauseAnimation::duration() const -{ - Q_D(const QPauseAnimation); - return d->duration; -} - -void QPauseAnimation::setDuration(int msecs) -{ - if (msecs < 0) { - qWarning("QPauseAnimation::setDuration: cannot set a negative duration"); - return; - } - Q_D(QPauseAnimation); - d->duration = msecs; -} - -/*! - \reimp - */ -bool QPauseAnimation::event(QEvent *e) -{ - return QAbstractAnimation::event(e); -} - -/*! - \reimp - */ -void QPauseAnimation::updateCurrentTime(int msecs) -{ - Q_UNUSED(msecs); -} - - -QT_END_NAMESPACE - -#include "moc_qpauseanimation.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qpauseanimation.h b/src/corelib/animation/qpauseanimation.h deleted file mode 100644 index cb6e041..0000000 --- a/src/corelib/animation/qpauseanimation.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPAUSEANIMATION_P_H -#define QPAUSEANIMATION_P_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -#ifndef QT_NO_ANIMATION - -class QPauseAnimationPrivate; - -class Q_CORE_EXPORT QPauseAnimation : public QAbstractAnimation -{ - Q_OBJECT - Q_PROPERTY(int duration READ duration WRITE setDuration) -public: - QPauseAnimation(QObject *parent = 0); - QPauseAnimation(int msecs, QObject *parent = 0); - ~QPauseAnimation(); - - int duration() const; - void setDuration(int msecs); - -protected: - bool event(QEvent *e); - void updateCurrentTime(int msecs); - -private: - Q_DISABLE_COPY(QPauseAnimation) - Q_DECLARE_PRIVATE(QPauseAnimation) -}; - -#endif //QT_NO_ANIMATION - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QPAUSEANIMATION_P_H diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp deleted file mode 100644 index 9a17049..0000000 --- a/src/corelib/animation/qpropertyanimation.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QPropertyAnimation - \brief The QPropertyAnimation class animates Qt properties - \since 4.6 - \ingroup animation - - QPropertyAnimation interpolates over \l{Qt's Property System}{Qt - properties}. As property values are stored in \l{QVariant}s, the - class inherits QVariantAnimation, and supports animation of the - same \l{QVariant::Type}{variant types} as its super class. - - A class declaring properties must be a QObject. To make it - possible to animate a property, it must provide a setter (so that - QPropertyAnimation can set the property's value). Note that this - makes it possible to animate many of Qt's widgets. Let's look at - an example: - - \code - QPropertyAnimation animation(myWidget, "geometry"); - animation.setDuration(10000); - animation.setStartValue(QRect(0, 0, 100, 30)); - animation.setEndValue(QRect(250, 250, 100, 30)); - - animation.start(); - \endcode - - The property name and the QObject instance of which property - should be animated are passed to the constructor. You can then - specify the start and end value of the property. The procedure is - equal for properties in classes you have implemented - yourself--just check with QVariantAnimation that your QVariant - type is supported. - - The QVariantAnimation class description explains how to set up the - animation in detail. Note, however, that if a start value is not - set, the property will start at the value it had when the - QPropertyAnimation instance was created. - - QPropertyAnimation works like a charm on its own. For complex - animations that, for instance, contain several objects, - QAnimationGroup is provided. An animation group is an animation - that can contain other animations, and that can manage when its - animations are played. Look at QParallelAnimationGroup for an - example. - - \sa QVariantAnimation, QAnimationGroup, {The Animation Framework} -*/ - -#ifndef QT_NO_ANIMATION - -#include "qpropertyanimation.h" -#include "qanimationgroup.h" -#include - -#include "qpropertyanimation_p.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -typedef QPair QPropertyAnimationPair; -typedef QHash QPropertyAnimationHash; -Q_GLOBAL_STATIC(QPropertyAnimationHash, _q_runningAnimations); -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, guardHashLock, (QMutex::Recursive) ) - -void QPropertyAnimationPrivate::updateMetaProperty() -{ - if (!target || propertyName.isEmpty()) - return; - - if (hasMetaProperty == 0 && !property.isValid()) { - const QMetaObject *mo = target->metaObject(); - propertyIndex = mo->indexOfProperty(propertyName); - if (propertyIndex != -1) { - hasMetaProperty = 1; - property = mo->property(propertyIndex); - propertyType = property.userType(); - } else { - if (!target->dynamicPropertyNames().contains(propertyName)) - qWarning("QPropertyAnimation: you're trying to animate a non-existing property %s of your QObject", propertyName.constData()); - hasMetaProperty = 2; - } - } - - if (property.isValid()) - convertValues(propertyType); -} - -void QPropertyAnimationPrivate::updateProperty(const QVariant &newValue) -{ - if (!target || state == QAbstractAnimation::Stopped) - return; - - if (hasMetaProperty == 1) { - if (newValue.userType() == propertyType) { - //no conversion is needed, we directly call the QObject::qt_metacall - void *data = const_cast(newValue.constData()); - target->qt_metacall(QMetaObject::WriteProperty, propertyIndex, &data); - } else { - property.write(target, newValue); - } - } else { - target->setProperty(propertyName.constData(), newValue); - } -} - -void QPropertyAnimationPrivate::_q_targetDestroyed() -{ - Q_Q(QPropertyAnimation); - //we stop here so that this animation is removed from the global hash - q->stop(); - target = 0; -} - -/*! - Construct a QPropertyAnimation object. \a parent is passed to QObject's - constructor. -*/ -QPropertyAnimation::QPropertyAnimation(QObject *parent) - : QVariantAnimation(*new QPropertyAnimationPrivate, parent) -{ -} - -/*! - Construct a QPropertyAnimation object. \a parent is passed to QObject's - constructor. The animation changes the property \a propertyName on \a - target. The default duration is 250ms. - - \sa targetObject, propertyName -*/ -QPropertyAnimation::QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent) - : QVariantAnimation(*new QPropertyAnimationPrivate, parent) -{ - setTargetObject(target); - setPropertyName(propertyName); -} - -/*! - Destroys the QPropertyAnimation instance. - */ -QPropertyAnimation::~QPropertyAnimation() -{ - stop(); -} - -/*! - \property QPropertyAnimation::targetObject - \brief the target QObject for this animation. - - This property defines the target QObject for this animation. - */ -QObject *QPropertyAnimation::targetObject() const -{ - Q_D(const QPropertyAnimation); - return d->target; -} - -void QPropertyAnimation::setTargetObject(QObject *target) -{ - Q_D(QPropertyAnimation); - if (d->target == target) - return; - - if (d->state != QAbstractAnimation::Stopped) { - qWarning("QPropertyAnimation::setTargetObject: you can't change the target of a running animation"); - return; - } - - //we need to get notified when the target is destroyed - if (d->target) - disconnect(d->target, SIGNAL(destroyed()), this, SLOT(_q_targetDestroyed())); - - if (target) - connect(target, SIGNAL(destroyed()), SLOT(_q_targetDestroyed())); - - d->target = target; - d->hasMetaProperty = 0; - d->updateMetaProperty(); -} - -/*! - \property QPropertyAnimation::propertyName - \brief the target property name for this animation - - This property defines the target property name for this animation. The - property name is required for the animation to operate. - */ -QByteArray QPropertyAnimation::propertyName() const -{ - Q_D(const QPropertyAnimation); - return d->propertyName; -} - -void QPropertyAnimation::setPropertyName(const QByteArray &propertyName) -{ - Q_D(QPropertyAnimation); - if (d->state != QAbstractAnimation::Stopped) { - qWarning("QPropertyAnimation::setPropertyName: you can't change the property name of a running animation"); - return; - } - - d->propertyName = propertyName; - d->hasMetaProperty = 0; - d->updateMetaProperty(); -} - - -/*! - \reimp - */ -bool QPropertyAnimation::event(QEvent *event) -{ - return QVariantAnimation::event(event); -} - -/*! - This virtual function is called by QVariantAnimation whenever the current value - changes. \a value is the new, updated value. It updates the current value - of the property on the target object. - - \sa currentValue, currentTime - */ -void QPropertyAnimation::updateCurrentValue(const QVariant &value) -{ - Q_D(QPropertyAnimation); - d->updateProperty(value); -} - -/*! - \reimp - - If the startValue is not defined when the state of the animation changes from Stopped to Running, - the current property value is used as the initial value for the animation. -*/ -void QPropertyAnimation::updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) -{ - Q_D(QPropertyAnimation); - - if (!d->target) { - qWarning("QPropertyAnimation::updateState: Changing state of an animation without target"); - return; - } - - QVariantAnimation::updateState(oldState, newState); - QMutexLocker locker(guardHashLock()); - QPropertyAnimationHash * hash = _q_runningAnimations(); - QPropertyAnimationPair key(d->target, d->propertyName); - if (newState == Running) { - d->updateMetaProperty(); - QPropertyAnimation *oldAnim = hash->value(key, 0); - if (oldAnim) { - // try to stop the top level group - QAbstractAnimation *current = oldAnim; - while (current->group() && current->state() != Stopped) - current = current->group(); - current->stop(); - } - hash->insert(key, this); - - // update the default start value - if (oldState == Stopped) { - d->setDefaultStartValue(d->target->property(d->propertyName.constData())); - } - } else if (hash->value(key) == this) { - hash->remove(key); - } -} - -#include "moc_qpropertyanimation.cpp" - -QT_END_NAMESPACE - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h deleted file mode 100644 index 5b06bd2..0000000 --- a/src/corelib/animation/qpropertyanimation.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPROPERTYANIMATION_H -#define QPROPERTYANIMATION_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -#ifndef QT_NO_ANIMATION - -class QPropertyAnimationPrivate; -class Q_CORE_EXPORT QPropertyAnimation : public QVariantAnimation -{ - Q_OBJECT - Q_PROPERTY(QByteArray propertyName READ propertyName WRITE setPropertyName) - Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject) - -public: - QPropertyAnimation(QObject *parent = 0); - QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0); - ~QPropertyAnimation(); - - QObject *targetObject() const; - void setTargetObject(QObject *target); - - QByteArray propertyName() const; - void setPropertyName(const QByteArray &propertyName); - -protected: - bool event(QEvent *event); - - void updateCurrentValue(const QVariant &value); - void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - Q_PRIVATE_SLOT(d_func(), void _q_targetDestroyed()); -private: - Q_DISABLE_COPY(QPropertyAnimation) - Q_DECLARE_PRIVATE(QPropertyAnimation) -}; - -#endif //QT_NO_ANIMATION - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QPROPERTYANIMATION_H diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h deleted file mode 100644 index b51d039..0000000 --- a/src/corelib/animation/qpropertyanimation_p.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPROPERTYANIMATION_P_H -#define QPROPERTYANIMATION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of QIODevice. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qpropertyanimation.h" -#include - -#include "qvariantanimation_p.h" - -QT_BEGIN_NAMESPACE - -class QPropertyAnimationPrivate : public QVariantAnimationPrivate -{ - Q_DECLARE_PUBLIC(QPropertyAnimation) -public: - QPropertyAnimationPrivate() - : target(0), propertyType(0), propertyIndex(0), hasMetaProperty(false) - { - } - - void _q_targetDestroyed(); - - QObject *target; - - //for the QProperty - QMetaProperty property; - int propertyType; - int propertyIndex; - - int hasMetaProperty; - QByteArray propertyName; - void updateProperty(const QVariant &); - void updateMetaProperty(); -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp deleted file mode 100644 index 14814a7..0000000 --- a/src/corelib/animation/qsequentialanimationgroup.cpp +++ /dev/null @@ -1,594 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QSequentialAnimationGroup - \brief The QSequentialAnimationGroup class provides a sequential group of animations. - \since 4.6 - \ingroup animation - - QSequentialAnimationGroup is a QAnimationGroup that runs its - animations in sequence, i.e., it starts one animation after - another has finished playing. The animations are played in the - order they are added to the group (using - \l{QAnimationGroup::}{addAnimation()} or - \l{QAnimationGroup::}{insertAnimationAt()}). The animation group - finishes when its last animation has finished. - - At each moment there is at most one animation that is active in - the group; it is returned by currentAnimation(). An empty group - has no current animation. - - A sequential animation group can be treated as any other - animation, i.e., it can be started, stopped, and added to other - groups. You can also call addPause() or insertPauseAt() to add a - pause to a sequential animation group. - - \code - QSequentialAnimationGroup group; - - group.addAnimation(anim1); - group.addAnimation(anim2); - - group.start(); - \endcode - - In this example, \c anim1 and \c anim2 are two already set up - \l{QPropertyAnimation}s. - - \sa QAnimationGroup, QAbstractAnimation, {The Animation Framework} -*/ - -#ifndef QT_NO_ANIMATION - -#include "qsequentialanimationgroup.h" -#include "qsequentialanimationgroup_p.h" - -#include "qpauseanimation.h" - -#include - -QT_BEGIN_NAMESPACE - - - -bool QSequentialAnimationGroupPrivate::atEnd() const -{ - // we try to detect if we're at the end of the group - //this is true if the following conditions are true: - // 1. we're in the last loop - // 2. the direction is forward - // 3. the current animation is the last one - // 4. the current animation has reached its end - const int animTotalCurrentTime = QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime; - return (currentLoop == loopCount - 1 - && direction == QAbstractAnimation::Forward - && currentAnimation == animations.last() - && animTotalCurrentTime == animationActualTotalDuration(currentAnimationIndex)); -} - -int QSequentialAnimationGroupPrivate::animationActualTotalDuration(int index) const -{ - QAbstractAnimation *anim = animations.at(index); - int ret = anim->totalDuration(); - if (ret == -1 && actualDuration.size() > index) - ret = actualDuration.at(index); //we can try the actual duration there - return ret; -} - -QSequentialAnimationGroupPrivate::AnimationIndex QSequentialAnimationGroupPrivate::indexForTime(int msecs) const -{ - Q_Q(const QSequentialAnimationGroup); - Q_ASSERT(!animations.isEmpty()); - - AnimationIndex ret; - int duration = 0; - - // in case duration is -1, currentLoop will always be 0 - ret.timeOffset = currentLoop * q->duration(); - - for (int i = 0; i < animations.size(); ++i) { - duration = animationActualTotalDuration(i); - - // 'animation' is the current animation if one of these reasons is true: - // 1. it's duration is undefined - // 2. it ends after msecs - // 3. it is the last animation (this can happen in case there is at least 1 uncontrolled animation) - // 4. it ends exactly in msecs and the direction is backwards - if (duration == -1 || msecs < (ret.timeOffset + duration) - || (msecs == (ret.timeOffset + duration) && direction == QAbstractAnimation::Backward)) { - ret.index = i; - return ret; - } - - // 'animation' has a non-null defined duration and is not the one at time 'msecs'. - ret.timeOffset += duration; - } - - // this can only happen when one of those conditions is true: - // 1. the duration of the group is undefined and we passed its actual duration - // 2. there are only 0-duration animations in the group - ret.timeOffset -= duration; - ret.index = animations.size() - 1; - return ret; -} - -void QSequentialAnimationGroupPrivate::restart() -{ - // restarting the group by making the first/last animation the current one - if (direction == QAbstractAnimation::Forward) { - lastLoop = 0; - if (currentAnimationIndex == 0) - activateCurrentAnimation(); - else - setCurrentAnimation(0); - } else { // direction == QAbstractAnimation::Backward - lastLoop = loopCount - 1; - int index = animations.size() - 1; - if (currentAnimationIndex == index) - activateCurrentAnimation(); - else - setCurrentAnimation(index); - } -} - -/*! - \internal - This manages advancing the execution of a group running forwards (time has gone forward), - which is the same behaviour for rewinding the execution of a group running backwards - (time has gone backward). -*/ -void QSequentialAnimationGroupPrivate::advanceForwards(const AnimationIndex &newAnimationIndex) -{ - if (lastLoop < currentLoop) { - // we need to fast forward to the end - for (int i = currentAnimationIndex; i < animations.size(); ++i) { - QAbstractAnimation *anim = animations.at(i); - setCurrentAnimation(i, true); - anim->setCurrentTime(animationActualTotalDuration(i)); - } - // this will make sure the current animation is reset to the beginning - if (animations.size() == 1) - // we need to force activation because setCurrentAnimation will have no effect - activateCurrentAnimation(); - else - setCurrentAnimation(0, true); - } - - // and now we need to fast forward from the current position to - for (int i = currentAnimationIndex; i < newAnimationIndex.index; ++i) { //### WRONG, - QAbstractAnimation *anim = animations.at(i); - setCurrentAnimation(i, true); - anim->setCurrentTime(animationActualTotalDuration(i)); - } - // setting the new current animation will happen later -} - -/*! - \internal - This manages rewinding the execution of a group running forwards (time has gone forward), - which is the same behaviour for advancing the execution of a group running backwards - (time has gone backward). -*/ -void QSequentialAnimationGroupPrivate::rewindForwards(const AnimationIndex &newAnimationIndex) -{ - if (lastLoop > currentLoop) { - // we need to fast rewind to the beginning - for (int i = currentAnimationIndex; i >= 0 ; --i) { - QAbstractAnimation *anim = animations.at(i); - setCurrentAnimation(i, true); - anim->setCurrentTime(0); - } - // this will make sure the current animation is reset to the end - if (animations.size() == 1) - // we need to force activation because setCurrentAnimation will have no effect - activateCurrentAnimation(); - else - setCurrentAnimation(animations.count() - 1, true); - } - - // and now we need to fast rewind from the current position to - for (int i = currentAnimationIndex; i > newAnimationIndex.index; --i) { - QAbstractAnimation *anim = animations.at(i); - setCurrentAnimation(i, true); - anim->setCurrentTime(0); - } - // setting the new current animation will happen later -} - -/*! - \fn QSequentialAnimationGroup::currentAnimationChanged(QAbstractAnimation *current) - - QSequentialAnimationGroup emits this signal when currentAnimation - has been changed. \a current is the current animation. - - \sa currentAnimation() -*/ - - -/*! - Constructs a QSequentialAnimationGroup. - \a parent is passed to QObject's constructor. -*/ -QSequentialAnimationGroup::QSequentialAnimationGroup(QObject *parent) - : QAnimationGroup(*new QSequentialAnimationGroupPrivate, parent) -{ -} - -/*! - \internal -*/ -QSequentialAnimationGroup::QSequentialAnimationGroup(QSequentialAnimationGroupPrivate &dd, - QObject *parent) - : QAnimationGroup(dd, parent) -{ -} - -/*! - Destroys the animation group. It will also destroy all its animations. -*/ -QSequentialAnimationGroup::~QSequentialAnimationGroup() -{ -} - -/*! - Adds a pause of \a msecs to this animation group. - The pause is considered as a special type of animation, thus count() will be - increased by one. - \sa insertPauseAt(), QAnimationGroup::addAnimation() -*/ -QPauseAnimation *QSequentialAnimationGroup::addPause(int msecs) -{ - QPauseAnimation *pause = new QPauseAnimation(msecs); - addAnimation(pause); - return pause; -} - -/*! - Inserts a pause of \a msecs milliseconds at \a index in this animation - group. - - \sa addPause(), QAnimationGroup::insertAnimationAt() -*/ -QPauseAnimation *QSequentialAnimationGroup::insertPauseAt(int index, int msecs) -{ - Q_D(const QSequentialAnimationGroup); - - if (index < 0 || index > d->animations.size()) { - qWarning("QSequentialAnimationGroup::insertPauseAt: index is out of bounds"); - return 0; - } - - QPauseAnimation *pause = new QPauseAnimation(msecs); - insertAnimationAt(index, pause); - return pause; -} - - -/*! - \property QSequentialAnimationGroup::currentAnimation - Returns the animation in the current time. - - \sa currentAnimationChanged() -*/ -QAbstractAnimation *QSequentialAnimationGroup::currentAnimation() const -{ - Q_D(const QSequentialAnimationGroup); - return d->currentAnimation; -} - -/*! - \reimp -*/ -int QSequentialAnimationGroup::duration() const -{ - Q_D(const QSequentialAnimationGroup); - int ret = 0; - - for (int i = 0; i < d->animations.size(); ++i) { - QAbstractAnimation *animation = d->animations.at(i); - const int currentDuration = animation->totalDuration(); - if (currentDuration == -1) - return -1; // Undetermined length - - ret += currentDuration; - } - - return ret; -} - -/*! - \reimp -*/ -void QSequentialAnimationGroup::updateCurrentTime(int msecs) -{ - Q_D(QSequentialAnimationGroup); - if (!d->currentAnimation) - return; - - const QSequentialAnimationGroupPrivate::AnimationIndex newAnimationIndex = d->indexForTime(msecs); - - // remove unneeded animations from actualDuration list - while (newAnimationIndex.index < d->actualDuration.size()) - d->actualDuration.removeLast(); - - // newAnimationIndex.index is the new current animation - if (d->lastLoop < d->currentLoop - || (d->lastLoop == d->currentLoop && d->currentAnimationIndex < newAnimationIndex.index)) { - // advancing with forward direction is the same as rewinding with backwards direction - d->advanceForwards(newAnimationIndex); - } else if (d->lastLoop > d->currentLoop - || (d->lastLoop == d->currentLoop && d->currentAnimationIndex > newAnimationIndex.index)) { - // rewinding with forward direction is the same as advancing with backwards direction - d->rewindForwards(newAnimationIndex); - } - - d->setCurrentAnimation(newAnimationIndex.index); - - const int newCurrentTime = msecs - newAnimationIndex.timeOffset; - - if (d->currentAnimation) { - d->currentAnimation->setCurrentTime(newCurrentTime); - if (d->atEnd()) { - //we make sure that we don't exceed the duration here - d->currentTime += QAbstractAnimationPrivate::get(d->currentAnimation)->totalCurrentTime - newCurrentTime; - stop(); - } - } else { - //the only case where currentAnimation could be null - //is when all animations have been removed - Q_ASSERT(d->animations.isEmpty()); - d->currentTime = 0; - stop(); - } - - d->lastLoop = d->currentLoop; -} - -/*! - \reimp -*/ -void QSequentialAnimationGroup::updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) -{ - Q_D(QSequentialAnimationGroup); - QAnimationGroup::updateState(oldState, newState); - - if (!d->currentAnimation) - return; - - switch (newState) { - case Stopped: - d->currentAnimation->stop(); - break; - case Paused: - if (oldState == d->currentAnimation->state() - && oldState == QSequentialAnimationGroup::Running) { - d->currentAnimation->pause(); - } - else - d->restart(); - break; - case Running: - if (oldState == d->currentAnimation->state() - && oldState == QSequentialAnimationGroup::Paused) - d->currentAnimation->start(); - else - d->restart(); - break; - } -} - -/*! - \reimp -*/ -void QSequentialAnimationGroup::updateDirection(QAbstractAnimation::Direction direction) -{ - Q_D(QSequentialAnimationGroup); - // we need to update the direction of the current animation - if (state() != Stopped && d->currentAnimation) - d->currentAnimation->setDirection(direction); -} - -/*! - \reimp -*/ -bool QSequentialAnimationGroup::event(QEvent *event) -{ - return QAnimationGroup::event(event); -} - -void QSequentialAnimationGroupPrivate::setCurrentAnimation(int index, bool intermediate) -{ - Q_Q(QSequentialAnimationGroup); - - index = qMin(index, animations.count() - 1); - - if (index == -1) { - Q_ASSERT(animations.isEmpty()); - currentAnimationIndex = -1; - currentAnimation = 0; - return; - } - - // need these two checks below because this func can be called after the current animation - // has been removed - if (index == currentAnimationIndex && animations.at(index) == currentAnimation) - return; - - // stop the old current animation - if (currentAnimation) - currentAnimation->stop(); - - currentAnimation = animations.at(index); - currentAnimationIndex = index; - - emit q->currentAnimationChanged(currentAnimation); - - activateCurrentAnimation(intermediate); -} - -void QSequentialAnimationGroupPrivate::activateCurrentAnimation(bool intermediate) -{ - Q_Q(QSequentialAnimationGroup); - - if (!currentAnimation) - return; - - if (state == QSequentialAnimationGroup::Stopped) - return; - - currentAnimation->stop(); - - // we ensure the direction is consistent with the group's direction - currentAnimation->setDirection(direction); - - // connects to the finish signal of uncontrolled animations - if (currentAnimation->totalDuration() == -1) - QObject::connect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); - - currentAnimation->start(); - if (!intermediate && state == QSequentialAnimationGroup::Paused) - currentAnimation->pause(); -} - -void QSequentialAnimationGroupPrivate::_q_uncontrolledAnimationFinished() -{ - Q_Q(QSequentialAnimationGroup); - Q_ASSERT(qobject_cast(q->sender()) == currentAnimation); - - // we trust the duration returned by the animation - while (actualDuration.size() < (currentAnimationIndex + 1)) - actualDuration.append(-1); - actualDuration[currentAnimationIndex] = currentAnimation->currentTime(); - - QObject::disconnect(currentAnimation, SIGNAL(finished()), q, SLOT(_q_uncontrolledAnimationFinished())); - - if ((direction == QAbstractAnimation::Forward && currentAnimation == animations.last()) - || (direction == QAbstractAnimation::Backward && currentAnimationIndex == 0)) { - // we don't handle looping of a group with undefined duration - q->stop(); - } else if (direction == QAbstractAnimation::Forward) { - // set the current animation to be the next one - setCurrentAnimation(currentAnimationIndex + 1); - } else { - // set the current animation to be the previous one - setCurrentAnimation(currentAnimationIndex - 1); - } -} - -/*! - \internal - This method is called whenever an animation is added to - the group at index \a index. - Note: We only support insertion after the current animation -*/ -void QSequentialAnimationGroupPrivate::animationInsertedAt(int index) -{ - if (currentAnimation == 0) - setCurrentAnimation(0); // initialize the current animation - - if (currentAnimationIndex == index - && currentAnimation->currentTime() == 0 && currentAnimation->currentLoop() == 0) { - //in this case we simply insert an animation before the current one has actually started - setCurrentAnimation(index); - } - - //we update currentAnimationIndex in case it has changed (the animation pointer is still valid) - currentAnimationIndex = animations.indexOf(currentAnimation); - - if (index < currentAnimationIndex || currentLoop != 0) { - qWarning("QSequentialGroup::insertAnimationAt only supports to add animations after the current one."); - return; //we're not affected because it is added after the current one - } -} - -/*! - \internal - This method is called whenever an animation is removed from - the group at index \a index. The animation is no more listed when this - method is called. -*/ -void QSequentialAnimationGroupPrivate::animationRemovedAt(int index) -{ - Q_Q(QSequentialAnimationGroup); - QAnimationGroupPrivate::animationRemovedAt(index); - - Q_ASSERT(currentAnimation); // currentAnimation should always be set - - if (actualDuration.size() > index) - actualDuration.removeAt(index); - - const int currentIndex = animations.indexOf(currentAnimation); - if (currentIndex == -1) { - //we're removing the current animation, let's update it to another one - if (index < animations.count()) - setCurrentAnimation(index); //let's try to take the next one - else if (index > 0) - setCurrentAnimation(index - 1); - else// case all animations were removed - setCurrentAnimation(-1); - } else if (currentAnimationIndex > index) { - currentAnimationIndex--; - } - - // duration of the previous animations up to the current animation - currentTime = 0; - for (int i = 0; i < currentAnimationIndex; ++i) { - const int current = animationActualTotalDuration(i); - currentTime += current; - } - - if (currentIndex != -1) { - //the current animation is not the one being removed - //so we add its current time to the current time of this group - currentTime += QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime; - } - - //let's also update the total current time - totalCurrentTime = currentTime + loopCount * q->duration(); -} - -QT_END_NAMESPACE - -#include "moc_qsequentialanimationgroup.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qsequentialanimationgroup.h b/src/corelib/animation/qsequentialanimationgroup.h deleted file mode 100644 index 4701a76..0000000 --- a/src/corelib/animation/qsequentialanimationgroup.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSEQUENTIALANIMATIONGROUP_H -#define QSEQUENTIALANIMATIONGROUP_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -#ifndef QT_NO_ANIMATION - -class QPauseAnimation; -class QSequentialAnimationGroupPrivate; - -class Q_CORE_EXPORT QSequentialAnimationGroup : public QAnimationGroup -{ - Q_OBJECT - Q_PROPERTY(QAbstractAnimation* currentAnimation READ currentAnimation NOTIFY currentAnimationChanged) - -public: - QSequentialAnimationGroup(QObject *parent = 0); - ~QSequentialAnimationGroup(); - - QPauseAnimation *addPause(int msecs); - QPauseAnimation *insertPauseAt(int index, int msecs); - - QAbstractAnimation *currentAnimation() const; - int duration() const; - -Q_SIGNALS: - void currentAnimationChanged(QAbstractAnimation *current); - -protected: - QSequentialAnimationGroup(QSequentialAnimationGroupPrivate &dd, QObject *parent); - bool event(QEvent *event); - - void updateCurrentTime(int msecs); - void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - void updateDirection(QAbstractAnimation::Direction direction); - -private: - Q_DISABLE_COPY(QSequentialAnimationGroup) - Q_DECLARE_PRIVATE(QSequentialAnimationGroup) - Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished()) -}; - -#endif //QT_NO_ANIMATION - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif //QSEQUENTIALANIMATIONGROUP_H diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h deleted file mode 100644 index 3ac90f8..0000000 --- a/src/corelib/animation/qsequentialanimationgroup_p.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSEQUENTIALANIMATIONGROUP_P_H -#define QSEQUENTIALANIMATIONGROUP_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of QIODevice. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qsequentialanimationgroup.h" -#include "qanimationgroup_p.h" - - -QT_BEGIN_NAMESPACE - -class QSequentialAnimationGroupPrivate : public QAnimationGroupPrivate -{ - Q_DECLARE_PUBLIC(QSequentialAnimationGroup) -public: - QSequentialAnimationGroupPrivate() - : currentAnimation(0), currentAnimationIndex(-1), lastLoop(0) - { } - - - struct AnimationIndex - { - AnimationIndex() : index(0), timeOffset(0) {} - // index points to the animation at timeOffset, skipping 0 duration animations. - // Note that the index semantic is slightly different depending on the direction. - int index; // the index of the animation in timeOffset - int timeOffset; // time offset when the animation at index starts. - }; - - int animationActualTotalDuration(int index) const; - AnimationIndex indexForTime(int msecs) const; - - void setCurrentAnimation(int index, bool intermediate = false); - void activateCurrentAnimation(bool intermediate = false); - - void animationInsertedAt(int index); - void animationRemovedAt(int index); - - bool atEnd() const; - - QAbstractAnimation *currentAnimation; - int currentAnimationIndex; - - // this is the actual duration of uncontrolled animations - // it helps seeking and even going forward - QList actualDuration; - - void restart(); - int lastLoop; - - // handle time changes - void rewindForwards(const AnimationIndex &newAnimationIndex); - void advanceForwards(const AnimationIndex &newAnimationIndex); - - // private slot - void _q_uncontrolledAnimationFinished(); -}; - -QT_END_NAMESPACE - -#endif //QSEQUENTIALANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp deleted file mode 100644 index a6834bb..0000000 --- a/src/corelib/animation/qvariantanimation.cpp +++ /dev/null @@ -1,644 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_NO_ANIMATION - -#include "qvariantanimation.h" -#include "qvariantanimation_p.h" - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -/*! - \class QVariantAnimation - \ingroup animation - \brief The QVariantAnimation class provides an abstract base class for animations. - \since 4.6 - - This class is part of \l{The Animation Framework}. It serves as a - base class for property and item animations, with functions for - shared functionality. - - QVariantAnimation cannot be used directly as it is an abstract - class; it does not implement - \l{QAbstractAnimation::}{updateCurrentValue()} from - QAbstractAnimation. The class performs interpolation over - \l{QVariant}s, but leaves using the interpolated values to its - subclasses. Currently, Qt provides QPropertyAnimation, which - animates Qt \l{Qt's Property System}{properties}. See the - QPropertyAnimation class description if you wish to animate such - properties. - - You can then set start and end values for the property by calling - setStartValue() and setEndValue(), and finally call start() to - start the animation. QVariantAnimation will interpolate the - property of the target object and emit valueChanged(). To react to - a change in the current value you have to reimplement the - updateCurrentValue() virtual function. - - It is also possible to set values at specified steps situated - between the start and end value. The interpolation will then - touch these points at the specified steps. Note that the start and - end values are defined as the key values at 0.0 and 1.0. - - There are two ways to affect how QVariantAnimation interpolates - the values. You can set an easing curve by calling - setEasingCurve(), and configure the duration by calling - setDuration(). You can change how the QVariants are interpolated - by creating a subclass of QVariantAnimation, and reimplementing - the virtual interpolated() function. - - Subclassing QVariantAnimation can be an alternative if you have - \l{QVariant}s that you do not wish to declare as Qt properties. - Note, however, that you in most cases will be better off declaring - your QVariant as a property. - - Not all QVariant types are supported. Below is a list of currently - supported QVariant types: - - \list - \o \l{QMetaType::}{Int} - \o \l{QMetaType::}{Double} - \o \l{QMetaType::}{Float} - \o \l{QMetaType::}{QLine} - \o \l{QMetaType::}{QLineF} - \o \l{QMetaType::}{QPoint} - \o \l{QMetaType::}{QSize} - \o \l{QMetaType::}{QSizeF} - \o \l{QMetaType::}{QRect} - \o \l{QMetaType::}{QRectF} - \endlist - - If you need to interpolate other variant types, including custom - types, you have to implement interpolation for these yourself. - You do this by reimplementing interpolated(), which returns - interpolation values for the value being interpolated. - - \omit We need some snippets around here. \endomit - - \sa QPropertyAnimation, QAbstractAnimation, {The Animation Framework} -*/ - -/*! - \fn void QVariantAnimation::valueChanged(const QVariant &value) - - QVariantAnimation emits this signal whenever the current \a value changes. - - \sa currentValue, startValue, endValue -*/ - -static bool animationValueLessThan(const QVariantAnimation::KeyValue &p1, const QVariantAnimation::KeyValue &p2) -{ - return p1.first < p2.first; -} - -template<> Q_INLINE_TEMPLATE QRect _q_interpolate(const QRect &f, const QRect &t, qreal progress) -{ - QRect ret; - ret.setCoords(_q_interpolate(f.left(), t.left(), progress), - _q_interpolate(f.top(), t.top(), progress), - _q_interpolate(f.right(), t.right(), progress), - _q_interpolate(f.bottom(), t.bottom(), progress)); - return ret; -} - -template<> Q_INLINE_TEMPLATE QRectF _q_interpolate(const QRectF &f, const QRectF &t, qreal progress) -{ - qreal x1, y1, w1, h1; - f.getRect(&x1, &y1, &w1, &h1); - qreal x2, y2, w2, h2; - t.getRect(&x2, &y2, &w2, &h2); - return QRectF(_q_interpolate(x1, x2, progress), _q_interpolate(y1, y2, progress), - _q_interpolate(w1, w2, progress), _q_interpolate(h1, h2, progress)); -} - -template<> Q_INLINE_TEMPLATE QLine _q_interpolate(const QLine &f, const QLine &t, qreal progress) -{ - return QLine( _q_interpolate(f.p1(), t.p1(), progress), _q_interpolate(f.p2(), t.p2(), progress)); -} - -template<> Q_INLINE_TEMPLATE QLineF _q_interpolate(const QLineF &f, const QLineF &t, qreal progress) -{ - return QLineF( _q_interpolate(f.p1(), t.p1(), progress), _q_interpolate(f.p2(), t.p2(), progress)); -} - -void QVariantAnimationPrivate::convertValues(int t) -{ - //this ensures that all the keyValues are of type t - for (int i = 0; i < keyValues.count(); ++i) { - QVariantAnimation::KeyValue &pair = keyValues[i]; - if (pair.second.userType() != t) - pair.second.convert(static_cast(t)); - } - interpolator = 0; // if the type changed we need to update the interpolator -} - -/*! - \internal - The goal of this function is to update the currentInterval member. As a consequence, we also - need to update the currentValue. - Set \a force to true to always recalculate the interval. -*/ -void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/) -{ - // can't interpolate if we have only 1 key value - if (keyValues.count() <= 1) - return; - - const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration))); - - if (force || progress < currentInterval.start.first || progress > currentInterval.end.first) { - //let's update currentInterval - QVariantAnimation::KeyValues::const_iterator itStart = qLowerBound(keyValues.constBegin(), - keyValues.constEnd(), - qMakePair(progress, QVariant()), - animationValueLessThan); - QVariantAnimation::KeyValues::const_iterator itEnd = itStart; - - // If we are at the end we should continue to use the last keyValues in case of extrapolation (progress > 1.0). - // This is because the easing function can return a value slightly outside the range [0, 1] - if (itStart != keyValues.constEnd()) { - // this can't happen because we always prepend the default start value there - if (itStart == keyValues.constBegin()) { - ++itEnd; - } else { - --itStart; - } - - // update all the values of the currentInterval - currentInterval.start = *itStart; - currentInterval.end = *itEnd; - } - } - setCurrentValueForProgress(progress); -} - -void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress) -{ - Q_Q(QVariantAnimation); - - const qreal startProgress = currentInterval.start.first; - const qreal endProgress = currentInterval.end.first; - const qreal localProgress = (progress - startProgress) / (endProgress - startProgress); - - QVariant ret = q->interpolated(currentInterval.start.second, - currentInterval.end.second, - localProgress); - qSwap(currentValue, ret); - q->updateCurrentValue(currentValue); - if ((connectedSignals & changedSignalMask) && currentValue != ret) { - //the value has changed - emit q->valueChanged(currentValue); - } -} - -QVariant QVariantAnimationPrivate::valueAt(qreal step) const -{ - QVariantAnimation::KeyValues::const_iterator result = - qBinaryFind(keyValues.begin(), keyValues.end(), qMakePair(step, QVariant()), animationValueLessThan); - if (result != keyValues.constEnd()) - return result->second; - - return QVariant(); -} - -void QVariantAnimationPrivate::setValueAt(qreal step, const QVariant &value) -{ - if (step < qreal(0.0) || step > qreal(1.0)) { - qWarning("QVariantAnimation::setValueAt: invalid step = %f", step); - return; - } - - QVariantAnimation::KeyValue pair(step, value); - - QVariantAnimation::KeyValues::iterator result = qLowerBound(keyValues.begin(), keyValues.end(), pair, animationValueLessThan); - if (result == keyValues.end() || result->first != step) { - keyValues.insert(result, pair); - } else { - if (value.isValid()) - result->second = value; // replaces the previous value - else if (step == 0 && !hasStartValue && defaultStartValue.isValid()) - result->second = defaultStartValue; // resets to the default start value - else - keyValues.erase(result); // removes the previous value - } - - recalculateCurrentInterval(/*force=*/true); -} - -void QVariantAnimationPrivate::setDefaultStartValue(const QVariant &value) -{ - defaultStartValue = value; - if (!hasStartValue) - setValueAt(0, value); -} - -/*! - Construct a QVariantAnimation object. \a parent is passed to QAbstractAnimation's - constructor. -*/ -QVariantAnimation::QVariantAnimation(QObject *parent) : QAbstractAnimation(*new QVariantAnimationPrivate, parent) -{ - d_func()->init(); -} - -/*! - \internal -*/ -QVariantAnimation::QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent) : QAbstractAnimation(dd, parent) -{ - d_func()->init(); -} - -/*! - Destroys the animation. -*/ -QVariantAnimation::~QVariantAnimation() -{ -} - -/*! - \property QVariantAnimation::easingCurve - \brief the easing curve of the animation - - This property defines the easing curve of the animation. By - default, a linear easing curve is used, resulting in linear - interpolation. Other curves are provided, for instance, - QEasingCurve::InCirc, which provides a circular entry curve. - Another example is QEasingCurve::InOutElastic, which provides an - elastic effect on the values of the interpolated variant. - - The easing curve is used with the interpolator, the interpolated() - virtual function, the animation's duration, and iterationCount, to - control how the current value changes as the animation progresses. -*/ -QEasingCurve QVariantAnimation::easingCurve() const -{ - Q_D(const QVariantAnimation); - return d->easing; -} - -void QVariantAnimation::setEasingCurve(const QEasingCurve &easing) -{ - Q_D(QVariantAnimation); - d->easing = easing; - d->recalculateCurrentInterval(); -} - -Q_GLOBAL_STATIC(QVector, registeredInterpolators) -Q_GLOBAL_STATIC(QReadWriteLock, registeredInterpolatorsLock) - -/*! - \fn void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) - \relates QVariantAnimation - \threadsafe - - Registers a custom interpolator \a func for the template type \c{T}. - The interpolator has to be registered before the animation is constructed. - To unregister (and use the default interpolator) set \a func to 0. - */ - -/*! - \internal - \typedef QVariantAnimation::Interpolator - - This is a typedef for a pointer to a function with the following - signature: - \code - QVariant myInterpolator(const QVariant &from, const QVariant &to, qreal progress); - \endcode - -*/ - -/*! \internal - * Registers a custom interpolator \a func for the specific \a interpolationType. - * The interpolator has to be registered before the animation is constructed. - * To unregister (and use the default interpolator) set \a func to 0. - */ -void QVariantAnimation::registerInterpolator(QVariantAnimation::Interpolator func, int interpolationType) -{ - // will override any existing interpolators - QWriteLocker locker(registeredInterpolatorsLock()); - if (int(interpolationType) >= registeredInterpolators()->count()) - registeredInterpolators()->resize(int(interpolationType) + 1); - registeredInterpolators()->replace(interpolationType, func); -} - - -template static inline QVariantAnimation::Interpolator castToInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) -{ - return reinterpret_cast(func); -} - -QVariantAnimation::Interpolator QVariantAnimationPrivate::getInterpolator(int interpolationType) -{ - QReadLocker locker(registeredInterpolatorsLock()); - QVariantAnimation::Interpolator ret = 0; - if (interpolationType < registeredInterpolators()->count()) { - ret = registeredInterpolators()->at(interpolationType); - if (ret) return ret; - } - - switch(interpolationType) - { - case QMetaType::Int: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::Double: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::Float: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::QLine: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::QLineF: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::QPoint: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::QPointF: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::QSize: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::QSizeF: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::QRect: - return castToInterpolator(_q_interpolateVariant); - case QMetaType::QRectF: - return castToInterpolator(_q_interpolateVariant); - default: - return 0; //this type is not handled - } -} - -/*! - \property QVariantAnimation::duration - \brief the duration of the animation - - This property describes the duration in milliseconds of the - animation. The default duration is 250 milliseconds. - - \sa QAbstractAnimation::duration() - */ -int QVariantAnimation::duration() const -{ - Q_D(const QVariantAnimation); - return d->duration; -} - -void QVariantAnimation::setDuration(int msecs) -{ - Q_D(QVariantAnimation); - if (msecs < 0) { - qWarning("QVariantAnimation::setDuration: cannot set a negative duration"); - return; - } - if (d->duration == msecs) - return; - d->duration = msecs; - d->recalculateCurrentInterval(); -} - -/*! - \property QVariantAnimation::startValue - \brief the optional start value of the animation - - This property describes the optional start value of the animation. If - omitted, or if a null QVariant is assigned as the start value, the - animation will use the current position of the end when the animation - is started. - - \sa endValue -*/ -QVariant QVariantAnimation::startValue() const -{ - return keyValueAt(0); -} - -void QVariantAnimation::setStartValue(const QVariant &value) -{ - setKeyValueAt(0, value); -} - -/*! - \property QVariantAnimation::endValue - \brief the end value of the animation - - This property describes the end value of the animation. - - \sa startValue - */ -QVariant QVariantAnimation::endValue() const -{ - return keyValueAt(1); -} - -void QVariantAnimation::setEndValue(const QVariant &value) -{ - setKeyValueAt(1, value); -} - - -/*! - Returns the key frame value for the given \a step. The given \a step - must be in the range 0 to 1. If there is no KeyValue for \a step, - it returns an invalid QVariant. - - \sa keyValues(), setKeyValueAt() -*/ -QVariant QVariantAnimation::keyValueAt(qreal step) const -{ - Q_D(const QVariantAnimation); - if (step == 0 && !d->hasStartValue) - return QVariant(); //special case where we don't have an explicit startValue - - return d->valueAt(step); -} - -/*! - \typedef QVariantAnimation::KeyValue - - This is a typedef for QPair. -*/ -/*! - \typedef QVariantAnimation::KeyValues - - This is a typedef for QVector -*/ - -/*! - Creates a key frame at the given \a step with the given \a value. - The given \a step must be in the range 0 to 1. - - \sa setKeyValues(), keyValueAt() -*/ -void QVariantAnimation::setKeyValueAt(qreal step, const QVariant &value) -{ - Q_D(QVariantAnimation); - if (step == 0) - d->hasStartValue = value.isValid(); - d->setValueAt(step, value); -} - -/*! - Returns the key frames of this animation. - - \sa keyValueAt(), setKeyValues() -*/ -QVariantAnimation::KeyValues QVariantAnimation::keyValues() const -{ - Q_D(const QVariantAnimation); - QVariantAnimation::KeyValues ret = d->keyValues; - //in case we added the default start value, we remove it - if (!d->hasStartValue && !ret.isEmpty() && ret.at(0).first == 0) - ret.remove(0); - return ret; -} - -/*! - Replaces the current set of key frames with the given \a keyValues. - the step of the key frames must be in the range 0 to 1. - - \sa keyValues(), keyValueAt() -*/ -void QVariantAnimation::setKeyValues(const KeyValues &keyValues) -{ - Q_D(QVariantAnimation); - d->keyValues = keyValues; - qSort(d->keyValues.begin(), d->keyValues.end(), animationValueLessThan); - d->hasStartValue = !d->keyValues.isEmpty() && d->keyValues.at(0).first == 0; - d->recalculateCurrentInterval(/*force=*/true); -} - -/*! - \property QVariantAnimation::currentValue - \brief the current value of the animation. - - This property describes the current value; an interpolated value - between the \l{startValue}{start value} and the \l{endValue}{end - value}, using the current time for progress. The value itself is - obtained from interpolated(), which is called repeatedly as the - animation is running. - - QVariantAnimation calls the virtual updateCurrentValue() function - when the current value changes. This is particularly useful for - subclasses that need to track updates. For example, - QPropertyAnimation uses this function to animate Qt \l{Qt's - Property System}{properties}. - - \sa startValue, endValue -*/ -QVariant QVariantAnimation::currentValue() const -{ - Q_D(const QVariantAnimation); - if (!d->currentValue.isValid()) - const_cast(d)->recalculateCurrentInterval(); - return d->currentValue; -} - -/*! - \reimp - */ -bool QVariantAnimation::event(QEvent *event) -{ - return QAbstractAnimation::event(event); -} - -/*! - \reimp -*/ -void QVariantAnimation::updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) -{ - Q_UNUSED(oldState); - Q_UNUSED(newState); -} - -/*! - - This virtual function returns the linear interpolation between - variants \a from and \a to, at \a progress, usually a value - between 0 and 1. You can reimplement this function in a subclass - of QVariantAnimation to provide your own interpolation algorithm. - - Note that in order for the interpolation to work with a - QEasingCurve that return a value smaller than 0 or larger than 1 - (such as QEasingCurve::InBack) you should make sure that it can - extrapolate. If the semantic of the datatype does not allow - extrapolation this function should handle that gracefully. - - You should call the QVariantAnimation implementation of this - function if you want your class to handle the types already - supported by Qt (see class QVariantAnimation description for a - list of supported types). - - \sa QEasingCurve - */ -QVariant QVariantAnimation::interpolated(const QVariant &from, const QVariant &to, qreal progress) const -{ - Q_D(const QVariantAnimation); - if (d->interpolator == 0) { - if (from.userType() == to.userType()) - d->interpolator = QVariantAnimationPrivate::getInterpolator(from.userType()); - if (d->interpolator == 0) //no interpolator found - return QVariant(); - } - - return d->interpolator(from.constData(), to.constData(), progress); -} - -/*! - \reimp - */ -void QVariantAnimation::updateCurrentTime(int msecs) -{ - Q_D(QVariantAnimation); - Q_UNUSED(msecs); - d->recalculateCurrentInterval(); -} - -QT_END_NAMESPACE - -#include "moc_qvariantanimation.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h deleted file mode 100644 index 5b90930..0000000 --- a/src/corelib/animation/qvariantanimation.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANIMATION_H -#define QANIMATION_H - -#include -#include -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -#ifndef QT_NO_ANIMATION - -class QVariantAnimationPrivate; -class Q_CORE_EXPORT QVariantAnimation : public QAbstractAnimation -{ - Q_OBJECT - Q_PROPERTY(QVariant startValue READ startValue WRITE setStartValue) - Q_PROPERTY(QVariant endValue READ endValue WRITE setEndValue) - Q_PROPERTY(QVariant currentValue READ currentValue NOTIFY currentValueChanged) - Q_PROPERTY(int duration READ duration WRITE setDuration) - Q_PROPERTY(QEasingCurve easingCurve READ easingCurve WRITE setEasingCurve) - -public: - typedef QPair KeyValue; - typedef QVector KeyValues; - - QVariantAnimation(QObject *parent = 0); - ~QVariantAnimation(); - - QVariant startValue() const; - void setStartValue(const QVariant &value); - - QVariant endValue() const; - void setEndValue(const QVariant &value); - - QVariant keyValueAt(qreal step) const; - void setKeyValueAt(qreal step, const QVariant &value); - - KeyValues keyValues() const; - void setKeyValues(const KeyValues &values); - - QVariant currentValue() const; - - int duration() const; - void setDuration(int msecs); - - QEasingCurve easingCurve() const; - void setEasingCurve(const QEasingCurve &easing); - - typedef QVariant (*Interpolator)(const void *from, const void *to, qreal progress); - -Q_SIGNALS: - void valueChanged(const QVariant &value); - -protected: - QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent = 0); - bool event(QEvent *event); - - void updateCurrentTime(int msecs); - void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - - virtual void updateCurrentValue(const QVariant &value) = 0; - virtual QVariant interpolated(const QVariant &from, const QVariant &to, qreal progress) const; - -private: - template friend void qRegisterAnimationInterpolator(QVariant (*func)(const T &, const T &, qreal)); - static void registerInterpolator(Interpolator func, int interpolationType); - - Q_DISABLE_COPY(QVariantAnimation) - Q_DECLARE_PRIVATE(QVariantAnimation) -}; - -template -static void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) { - QVariantAnimation::registerInterpolator(reinterpret_cast(func), qMetaTypeId()); -} - -#endif //QT_NO_ANIMATION - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif //QANIMATION_H diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h deleted file mode 100644 index 0d296db..0000000 --- a/src/corelib/animation/qvariantanimation_p.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANIMATION_P_H -#define QANIMATION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of QIODevice. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qvariantanimation.h" -#include -#include -#include - -#include "qabstractanimation_p.h" - -QT_BEGIN_NAMESPACE - -class QVariantAnimationPrivate : public QAbstractAnimationPrivate -{ - Q_DECLARE_PUBLIC(QVariantAnimation) -public: - - QVariantAnimationPrivate() : duration(250), hasStartValue(false) - { - } - - void init() - { - //we keep the mask so that we emit valueChanged only when needed (for performance reasons) - changedSignalMask = (1 << q_func()->metaObject()->indexOfSignal("valueChanged(QVariant)")); - currentInterval.start.first = currentInterval.end.first = 2; //will force the initial refresh - interpolator = 0; - } - - static QVariantAnimationPrivate *get(QVariantAnimation *q) - { - return q->d_func(); - } - - void setDefaultStartValue(const QVariant &value); - - int duration; - QEasingCurve easing; - - QVariantAnimation::KeyValues keyValues; - QVariant currentValue; - QVariant defaultStartValue; - bool hasStartValue; - - //this is used to keep track of the KeyValue interval in which we currently are - struct - { - QVariantAnimation::KeyValue start, end; - } currentInterval; - - mutable QVariantAnimation::Interpolator interpolator; - - quint32 changedSignalMask; - - void setCurrentValueForProgress(const qreal progress); - void recalculateCurrentInterval(bool force=false); - void setValueAt(qreal, const QVariant &); - QVariant valueAt(qreal step) const; - void convertValues(int t); - - static QVariantAnimation::Interpolator getInterpolator(int interpolationType); -}; - -//this should make the interpolation faster -template inline T _q_interpolate(const T &f, const T &t, qreal progress) -{ - return T(f + (t - f) * progress); -} - -template inline QVariant _q_interpolateVariant(const T &from, const T &to, qreal progress) -{ - return _q_interpolate(from, to, progress); -} - - -QT_END_NAMESPACE - -#endif //QANIMATION_P_H diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index db51d43..f99d57f 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -5,7 +5,6 @@ DEFINES += QT_BUILD_CORE_LIB QT_NO_USING_NAMESPACE win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000 include(../qbase.pri) -include(animation/animation.pri) include(arch/arch.pri) include(concurrent/concurrent.pri) include(global/global.pri) @@ -15,7 +14,6 @@ include(io/io.pri) include(plugin/plugin.pri) include(kernel/kernel.pri) include(codecs/codecs.pri) -include(statemachine/statemachine.pri) include(xml/xml.pri) mac|darwin:LIBS += -framework ApplicationServices diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index ecef555..68649a6 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -12,7 +12,7 @@ HEADERS += \ kernel/qcoreevent.h \ kernel/qmetaobject.h \ kernel/qmetatype.h \ - kernel/qmimedata.h \ + kernel/qmimedata.h \ kernel/qobject.h \ kernel/qobjectdefs.h \ kernel/qsignalmapper.h \ @@ -27,8 +27,8 @@ HEADERS += \ kernel/qvariant_p.h \ kernel/qmetaobject_p.h \ kernel/qobject_p.h \ - kernel/qcoreglobaldata_p.h \ - kernel/qsharedmemory.h \ + kernel/qcoreglobaldata_p.h \ + kernel/qsharedmemory.h \ kernel/qsharedmemory_p.h \ kernel/qsystemsemaphore.h \ kernel/qsystemsemaphore_p.h \ @@ -43,7 +43,7 @@ SOURCES += \ kernel/qcoreevent.cpp \ kernel/qmetaobject.cpp \ kernel/qmetatype.cpp \ - kernel/qmimedata.cpp \ + kernel/qmimedata.cpp \ kernel/qobject.cpp \ kernel/qobjectcleanuphandler.cpp \ kernel/qsignalmapper.cpp \ diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index d6b0174..11a2d3c 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -264,8 +264,6 @@ QT_BEGIN_NAMESPACE \omitvalue NetworkReplyUpdated \omitvalue FutureCallOut \omitvalue CocoaRequestModal - \omitvalue Wrapped - \omitvalue Signal */ /*! diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 18188a8..fa472e6 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -44,7 +44,6 @@ #include #include -#include QT_BEGIN_HEADER @@ -55,9 +54,7 @@ QT_MODULE(Core) class QEventPrivate; class Q_CORE_EXPORT QEvent // event base class { - Q_GADGET QDOC_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) - Q_ENUMS(Type) public: enum Type { /* @@ -269,10 +266,7 @@ public: CocoaRequestModal = 190, // Internal for requesting an application modal Cocoa Window MacGLClearDrawable = 191, // Internal Cocoa, the window has changed, so we must clear - Signal = 192, - Wrapped = 193, - - // 512 reserved for Qt Jambi's MetaCall event + // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event User = 1000, // first user event id diff --git a/src/corelib/statemachine/qabstractstate.cpp b/src/corelib/statemachine/qabstractstate.cpp deleted file mode 100644 index 942722f..0000000 --- a/src/corelib/statemachine/qabstractstate.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qabstractstate.h" -#include "qabstractstate_p.h" -#include "qstate.h" -#include "qstate_p.h" -#include "qstatemachine.h" -#include "qstatemachine_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QAbstractState - - \brief The QAbstractState class is the base class of states of a QStateMachine. - - \since 4.6 - \ingroup statemachine - - The QAbstractState class is the abstract base class of states that are part - of a QStateMachine. It defines the interface that all state objects have in - common. QAbstractState is part of \l{The State Machine Framework}. - - The entered() signal is emitted when the state has been entered. The - exited() signal is emitted when the state has been exited. - - The parentState() function returns the state's parent state. The machine() - function returns the state machine that the state is part of. - - \section1 Subclassing - - The onEntry() function is called when the state is entered; reimplement this - function to perform custom processing when the state is entered. - - The onExit() function is called when the state is exited; reimplement this - function to perform custom processing when the state is exited. -*/ - -QAbstractStatePrivate::QAbstractStatePrivate() -{ -} - -QAbstractStatePrivate *QAbstractStatePrivate::get(QAbstractState *q) -{ - return q->d_func(); -} - -QStateMachine *QAbstractStatePrivate::machine() const -{ - Q_Q(const QAbstractState); - QObject *par = q->parent(); - while (par != 0) { - if (QStateMachine *mach = qobject_cast(par)) - return mach; - par = par->parent(); - } - return 0; -} - -void QAbstractStatePrivate::callOnEntry(QEvent *e) -{ - Q_Q(QAbstractState); - q->onEntry(e); -} - -void QAbstractStatePrivate::callOnExit(QEvent *e) -{ - Q_Q(QAbstractState); - q->onExit(e); -} - -void QAbstractStatePrivate::emitEntered() -{ - Q_Q(QAbstractState); - emit q->entered(); -} - -void QAbstractStatePrivate::emitExited() -{ - Q_Q(QAbstractState); - emit q->exited(); -} - -/*! - Constructs a new state with the given \a parent state. -*/ -QAbstractState::QAbstractState(QState *parent) - : QObject(*new QAbstractStatePrivate, parent) -{ -} - -/*! - \internal -*/ -QAbstractState::QAbstractState(QAbstractStatePrivate &dd, QState *parent) - : QObject(dd, parent) -{ -} - -/*! - Destroys this state. -*/ -QAbstractState::~QAbstractState() -{ -} - -/*! - Returns this state's parent state, or 0 if the state has no parent state. -*/ -QState *QAbstractState::parentState() const -{ - return qobject_cast(parent()); -} - -/*! - Returns the state machine that this state is part of, or 0 if the state is - not part of a state machine. -*/ -QStateMachine *QAbstractState::machine() const -{ - Q_D(const QAbstractState); - return d->machine(); -} - -/*! - \fn QAbstractState::onExit(QEvent *event) - - This function is called when the state is exited. The given \a event is what - caused the state to be exited. Reimplement this function to perform custom - processing when the state is exited. -*/ - -/*! - \fn QAbstractState::onEntry(QEvent *event) - - This function is called when the state is entered. The given \a event is - what caused the state to be entered. Reimplement this function to perform - custom processing when the state is entered. -*/ - -/*! - \fn QAbstractState::entered() - - This signal is emitted when the state has been entered (after onEntry() has - been called). -*/ - -/*! - \fn QAbstractState::exited() - - This signal is emitted when the state has been exited (after onExit() has - been called). -*/ - -/*! - \reimp -*/ -bool QAbstractState::event(QEvent *e) -{ - return QObject::event(e); -} - -QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qabstractstate.h b/src/corelib/statemachine/qabstractstate.h deleted file mode 100644 index d0ebb52..0000000 --- a/src/corelib/statemachine/qabstractstate.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QABSTRACTSTATE_H -#define QABSTRACTSTATE_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QState; -class QStateMachine; - -class QAbstractStatePrivate; -class Q_CORE_EXPORT QAbstractState : public QObject -{ - Q_OBJECT -public: - ~QAbstractState(); - - QState *parentState() const; - QStateMachine *machine() const; - -Q_SIGNALS: - void entered(); - void exited(); - -protected: - QAbstractState(QState *parent = 0); - - virtual void onEntry(QEvent *event) = 0; - virtual void onExit(QEvent *event) = 0; - - bool event(QEvent *e); - -protected: - QAbstractState(QAbstractStatePrivate &dd, QState *parent); - -private: - Q_DISABLE_COPY(QAbstractState) - Q_DECLARE_PRIVATE(QAbstractState) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/qabstractstate_p.h b/src/corelib/statemachine/qabstractstate_p.h deleted file mode 100644 index 2aad47e..0000000 --- a/src/corelib/statemachine/qabstractstate_p.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QABSTRACTSTATE_P_H -#define QABSTRACTSTATE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -class QStateMachine; - -class QAbstractState; -class Q_CORE_EXPORT QAbstractStatePrivate - : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QAbstractState) - -public: - QAbstractStatePrivate(); - - static QAbstractStatePrivate *get(QAbstractState *q); - - QStateMachine *machine() const; - - void callOnEntry(QEvent *e); - void callOnExit(QEvent *e); - - void emitEntered(); - void emitExited(); -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp deleted file mode 100644 index dfcafeb..0000000 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qabstracttransition.h" -#include "qabstracttransition_p.h" -#include "qabstractstate.h" -#include "qstate.h" -#include "qstatemachine.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QAbstractTransition - - \brief The QAbstractTransition class is the base class of transitions between QAbstractState objects. - - \since 4.6 - \ingroup statemachine - - The QAbstractTransition class is the abstract base class of transitions - between states (QAbstractState objects) of a - QStateMachine. QAbstractTransition is part of \l{The State Machine - Framework}. - - The sourceState() function returns the source of the transition. The - targetStates() function returns the targets of the transition. The machine() - function returns the state machine that the transition is part of. - - Transitions can cause animations to be played. Use the addAnimation() - function to add an animation to the transition. - - \section1 Subclassing - - The eventTest() function is called by the state machine to determine whether - an event should trigger the transition. In your reimplementation you - typically check the event type and cast the event object to the proper type, - and check that one or more properties of the event meet your criteria. - - The onTransition() function is called when the transition is triggered; - reimplement this function to perform custom processing for the transition. -*/ - -/*! - \property QAbstractTransition::sourceState - - \brief the source state (parent) of this transition -*/ - -/*! - \property QAbstractTransition::targetState - - \brief the target state of this transition -*/ - -/*! - \property QAbstractTransition::targetStates - - \brief the target states of this transition - - If multiple states are specified, all must be descendants of the same - parallel group state. -*/ - -QAbstractTransitionPrivate::QAbstractTransitionPrivate() -{ -} - -QAbstractTransitionPrivate *QAbstractTransitionPrivate::get(QAbstractTransition *q) -{ - return q->d_func(); -} - -QStateMachine *QAbstractTransitionPrivate::machine() const -{ - Q_Q(const QAbstractTransition); - QObject *par = q->parent(); - while (par != 0) { - if (QStateMachine *mach = qobject_cast(par)) - return mach; - par = par->parent(); - } - return 0; -} - -bool QAbstractTransitionPrivate::callEventTest(QEvent *e) -{ - Q_Q(QAbstractTransition); - return q->eventTest(e); -} - -void QAbstractTransitionPrivate::callOnTransition(QEvent *e) -{ - Q_Q(QAbstractTransition); - q->onTransition(e); -} - -QState *QAbstractTransitionPrivate::sourceState() const -{ - Q_Q(const QAbstractTransition); - return qobject_cast(q->parent()); -} - -/*! - Constructs a new QAbstractTransition object with the given \a sourceState. -*/ -QAbstractTransition::QAbstractTransition(QState *sourceState) - : QObject(*new QAbstractTransitionPrivate, sourceState) -{ -} - -/*! - Constructs a new QAbstractTransition object with the given \a targets and \a - sourceState. -*/ -QAbstractTransition::QAbstractTransition(const QList &targets, - QState *sourceState) - : QObject(*new QAbstractTransitionPrivate, sourceState) -{ - setTargetStates(targets); -} - -/*! - \internal -*/ -QAbstractTransition::QAbstractTransition(QAbstractTransitionPrivate &dd, - QState *parent) - : QObject(dd, parent) -{ -} - -/*! - \internal -*/ -QAbstractTransition::QAbstractTransition(QAbstractTransitionPrivate &dd, - const QList &targets, - QState *parent) - : QObject(dd, parent) -{ - setTargetStates(targets); -} - -/*! - Destroys this transition. -*/ -QAbstractTransition::~QAbstractTransition() -{ -} - -/*! - Returns the source state of this transition, or 0 if this transition has no - source state. -*/ -QState *QAbstractTransition::sourceState() const -{ - Q_D(const QAbstractTransition); - return d->sourceState(); -} - -/*! - Returns the target state of this transition, or 0 if the transition has no - target. -*/ -QAbstractState *QAbstractTransition::targetState() const -{ - Q_D(const QAbstractTransition); - if (d->targetStates.isEmpty()) - return 0; - return d->targetStates.first(); -} - -/*! - Sets the \a target state of this transition. -*/ -void QAbstractTransition::setTargetState(QAbstractState* target) -{ - Q_D(QAbstractTransition); - if (!target) - d->targetStates.clear(); - else - setTargetStates(QList() << target); -} - -/*! - Returns the target states of this transition, or an empty list if this - transition has no target states. -*/ -QList QAbstractTransition::targetStates() const -{ - Q_D(const QAbstractTransition); - QList result; - for (int i = 0; i < d->targetStates.size(); ++i) { - QAbstractState *target = d->targetStates.at(i); - if (target) - result.append(target); - } - return result; -} - -/*! - Sets the target states of this transition to be the given \a targets. -*/ -void QAbstractTransition::setTargetStates(const QList &targets) -{ - Q_D(QAbstractTransition); - - for (int i=0; imachine() != 0 && target->machine()->rootState() == target) { - qWarning("QAbstractTransition::setTargetStates: root state cannot be target of transition"); - return; - } - } - - d->targetStates.clear(); - for (int i = 0; i < targets.size(); ++i) - d->targetStates.append(targets.at(i)); -} - -/*! - Returns the state machine that this transition is part of, or 0 if the - transition is not part of a state machine. -*/ -QStateMachine *QAbstractTransition::machine() const -{ - Q_D(const QAbstractTransition); - return d->machine(); -} - -#ifndef QT_NO_ANIMATION - -/*! - Adds the given \a animation to this transition. - The transition does not take ownership of the animation. - - \sa removeAnimation(), animations() -*/ -void QAbstractTransition::addAnimation(QAbstractAnimation *animation) -{ - Q_D(QAbstractTransition); - if (!animation) { - qWarning("QAbstractTransition::addAnimation: cannot add null animation"); - return; - } - d->animations.append(animation); -} - -/*! - Removes the given \a animation from this transition. - - \sa addAnimation() -*/ -void QAbstractTransition::removeAnimation(QAbstractAnimation *animation) -{ - Q_D(QAbstractTransition); - if (!animation) { - qWarning("QAbstractTransition::removeAnimation: cannot remove null animation"); - return; - } - d->animations.removeOne(animation); -} - -/*! - Returns the list of animations associated with this transition, or an empty - list if it has no animations. - - \sa addAnimation() -*/ -QList QAbstractTransition::animations() const -{ - Q_D(const QAbstractTransition); - return d->animations; -} - -#endif - -/*! - \fn QAbstractTransition::eventTest(QEvent *event) - - This function is called to determine whether the given \a event should cause - this transition to trigger. Reimplement this function and return true if the - event should trigger the transition, otherwise return false. -*/ - -/*! - \fn QAbstractTransition::onTransition(QEvent *event) - - This function is called when the transition is triggered. The given \a event - is what caused the transition to trigger. Reimplement this function to - perform custom processing when the transition is triggered. -*/ - -/*! - \reimp -*/ -bool QAbstractTransition::event(QEvent *e) -{ - return QObject::event(e); -} - -QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qabstracttransition.h b/src/corelib/statemachine/qabstracttransition.h deleted file mode 100644 index c63d55a..0000000 --- a/src/corelib/statemachine/qabstracttransition.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QABSTRACTTRANSITION_H -#define QABSTRACTTRANSITION_H - -#include - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QEvent; -class QAbstractState; -class QState; -class QStateMachine; - -#ifndef QT_NO_ANIMATION -class QAbstractAnimation; -#endif - -class QAbstractTransitionPrivate; -class Q_CORE_EXPORT QAbstractTransition : public QObject -{ - Q_OBJECT - Q_PROPERTY(QState* sourceState READ sourceState) - Q_PROPERTY(QAbstractState* targetState READ targetState WRITE setTargetState) - Q_PROPERTY(QList targetStates READ targetStates WRITE setTargetStates) -public: - QAbstractTransition(QState *sourceState = 0); - QAbstractTransition(const QList &targets, QState *sourceState = 0); - virtual ~QAbstractTransition(); - - QState *sourceState() const; - QAbstractState *targetState() const; - void setTargetState(QAbstractState* target); - QList targetStates() const; - void setTargetStates(const QList &targets); - - QStateMachine *machine() const; - -#ifndef QT_NO_ANIMATION - void addAnimation(QAbstractAnimation *animation); - void removeAnimation(QAbstractAnimation *animation); - QList animations() const; -#endif - -protected: - virtual bool eventTest(QEvent *event) = 0; - - virtual void onTransition(QEvent *event) = 0; - - bool event(QEvent *e); - -protected: - QAbstractTransition(QAbstractTransitionPrivate &dd, QState *parent); - QAbstractTransition(QAbstractTransitionPrivate &dd, - const QList &targets, QState *parent); - -private: - Q_DISABLE_COPY(QAbstractTransition) - Q_DECLARE_PRIVATE(QAbstractTransition) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h deleted file mode 100644 index f067984..0000000 --- a/src/corelib/statemachine/qabstracttransition_p.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QABSTRACTTRANSITION_P_H -#define QABSTRACTTRANSITION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -class QAbstractState; -class QState; -class QStateMachine; - -class QAbstractTransition; -class Q_CORE_EXPORT QAbstractTransitionPrivate - : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QAbstractTransition) -public: - QAbstractTransitionPrivate(); - - static QAbstractTransitionPrivate *get(QAbstractTransition *q); - - bool callEventTest(QEvent *e); - void callOnTransition(QEvent *e); - QState *sourceState() const; - QStateMachine *machine() const; - - QList > targetStates; - -#ifndef QT_NO_ANIMATION - QList animations; -#endif -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/corelib/statemachine/qeventtransition.cpp b/src/corelib/statemachine/qeventtransition.cpp deleted file mode 100644 index 74eb577..0000000 --- a/src/corelib/statemachine/qeventtransition.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeventtransition.h" -#include "qeventtransition_p.h" -#include "qwrappedevent.h" -#include "qstate.h" -#include "qstate_p.h" -#include "qstatemachine.h" -#include "qstatemachine_p.h" -#include - -QT_BEGIN_NAMESPACE - -/*! - \class QEventTransition - - \brief The QEventTransition class provides a QObject-specific transition for Qt events. - - \since 4.6 - \ingroup statemachine - - A QEventTransition object binds an event to a particular QObject. - QEventTransition is part of \l{The State Machine Framework}. - - Example: - - \code - QPushButton *button = ...; - QState *s1 = ...; - QState *s2 = ...; - // If in s1 and the button receives an Enter event, transition to s2 - QEventTransition *enterTransition = new QEventTransition(button, QEvent::Enter); - enterTransition->setTargetState(s2); - s1->addTransition(enterTransition); - // If in s2 and the button receives an Exit event, transition back to s1 - QEventTransition *leaveTransition = new QEventTransition(button, QEvent::Leave); - leaveTransition->setTargetState(s1); - s2->addTransition(leaveTransition); - \endcode - - \section1 Subclassing - - When reimplementing the eventTest() function, you should first call the base - implementation to verify that the event is a QWrappedEvent for the proper - object and event type. You may then cast the event to a QWrappedEvent and - get the original event by calling QWrappedEvent::event(), and perform - additional checks on that object. - - \sa QState::addTransition() -*/ - -/*! - \property QEventTransition::eventObject - - \brief the event source that this event transition is associated with -*/ - -/*! - \property QEventTransition::eventType - - \brief the type of event that this event transition is associated with -*/ -QEventTransitionPrivate::QEventTransitionPrivate() -{ - object = 0; - eventType = QEvent::None; - registered = false; -} - -QEventTransitionPrivate *QEventTransitionPrivate::get(QEventTransition *q) -{ - return q->d_func(); -} - -void QEventTransitionPrivate::invalidate() -{ - Q_Q(QEventTransition); - if (registered) { - QState *source = sourceState(); - QStatePrivate *source_d = QStatePrivate::get(source); - QStateMachinePrivate *mach = QStateMachinePrivate::get(source_d->machine()); - if (mach) { - mach->unregisterEventTransition(q); - if (mach->configuration.contains(source)) - mach->registerEventTransition(q); - } - } -} - -/*! - Constructs a new QEventTransition object with the given \a sourceState. -*/ -QEventTransition::QEventTransition(QState *sourceState) - : QAbstractTransition(*new QEventTransitionPrivate, sourceState) -{ -} - -/*! - Constructs a new QEventTransition object associated with events of the given - \a type for the given \a object, and with the given \a sourceState. -*/ -QEventTransition::QEventTransition(QObject *object, QEvent::Type type, - QState *sourceState) - : QAbstractTransition(*new QEventTransitionPrivate, sourceState) -{ - Q_D(QEventTransition); - d->registered = false; - d->object = object; - d->eventType = type; -} - -/*! - Constructs a new QEventTransition object associated with events of the given - \a type for the given \a object. The transition has the given \a targets and - \a sourceState. -*/ -QEventTransition::QEventTransition(QObject *object, QEvent::Type type, - const QList &targets, - QState *sourceState) - : QAbstractTransition(*new QEventTransitionPrivate, targets, sourceState) -{ - Q_D(QEventTransition); - d->registered = false; - d->object = object; - d->eventType = type; -} - -/*! - \internal -*/ -QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QState *parent) - : QAbstractTransition(dd, parent) -{ -} - -/*! - \internal -*/ -QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object, - QEvent::Type type, QState *parent) - : QAbstractTransition(dd, parent) -{ - Q_D(QEventTransition); - d->registered = false; - d->object = object; - d->eventType = type; -} - -/*! - \internal -*/ -QEventTransition::QEventTransition(QEventTransitionPrivate &dd, QObject *object, - QEvent::Type type, const QList &targets, - QState *parent) - : QAbstractTransition(dd, targets, parent) -{ - Q_D(QEventTransition); - d->registered = false; - d->object = object; - d->eventType = type; -} - -/*! - Destroys this QObject event transition. -*/ -QEventTransition::~QEventTransition() -{ -} - -/*! - Returns the event type that this event transition is associated with. -*/ -QEvent::Type QEventTransition::eventType() const -{ - Q_D(const QEventTransition); - return d->eventType; -} - -/*! - Sets the event \a type that this event transition is associated with. -*/ -void QEventTransition::setEventType(QEvent::Type type) -{ - Q_D(QEventTransition); - if (d->eventType == type) - return; - d->eventType = type; - d->invalidate(); -} - -/*! - Returns the event source associated with this event transition. -*/ -QObject *QEventTransition::eventObject() const -{ - Q_D(const QEventTransition); - return d->object; -} - -/*! - Sets the event source associated with this event transition to be the given - \a object. -*/ -void QEventTransition::setEventObject(QObject *object) -{ - Q_D(QEventTransition); - if (d->object == object) - return; - d->object = object; - d->invalidate(); -} - -/*! - \reimp -*/ -bool QEventTransition::eventTest(QEvent *event) -{ - Q_D(const QEventTransition); - if (event->type() == QEvent::Wrapped) { - QWrappedEvent *we = static_cast(event); - return (we->object() == d->object) - && (we->event()->type() == d->eventType); - } - return false; -} - -/*! - \reimp -*/ -void QEventTransition::onTransition(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \reimp -*/ -bool QEventTransition::event(QEvent *e) -{ - return QAbstractTransition::event(e); -} - -QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qeventtransition.h b/src/corelib/statemachine/qeventtransition.h deleted file mode 100644 index 3530bdd..0000000 --- a/src/corelib/statemachine/qeventtransition.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEVENTTRANSITION_H -#define QEVENTTRANSITION_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QEventTransitionPrivate; -class Q_CORE_EXPORT QEventTransition : public QAbstractTransition -{ - Q_OBJECT - Q_PROPERTY(QObject* eventObject READ eventObject WRITE setEventObject) - Q_PROPERTY(QEvent::Type eventType READ eventType WRITE setEventType) -public: - QEventTransition(QState *sourceState = 0); - QEventTransition(QObject *object, QEvent::Type type, QState *sourceState = 0); - QEventTransition(QObject *object, QEvent::Type type, - const QList &targets, QState *sourceState = 0); - ~QEventTransition(); - - QObject *eventObject() const; - void setEventObject(QObject *object); - - QEvent::Type eventType() const; - void setEventType(QEvent::Type type); - -protected: - bool eventTest(QEvent *event); - void onTransition(QEvent *event); - - bool event(QEvent *e); - -protected: - QEventTransition(QEventTransitionPrivate &dd, QState *parent); - QEventTransition(QEventTransitionPrivate &dd, QObject *object, - QEvent::Type type, QState *parent); - QEventTransition(QEventTransitionPrivate &dd, QObject *object, - QEvent::Type type, const QList &targets, - QState *parent); - -private: - Q_DISABLE_COPY(QEventTransition) - Q_DECLARE_PRIVATE(QEventTransition) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/qeventtransition_p.h b/src/corelib/statemachine/qeventtransition_p.h deleted file mode 100644 index fca8c0d..0000000 --- a/src/corelib/statemachine/qeventtransition_p.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEVENTTRANSITION_P_H -#define QEVENTTRANSITION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qabstracttransition_p.h" - -QT_BEGIN_NAMESPACE - -class QEventTransition; -class Q_CORE_EXPORT QEventTransitionPrivate : public QAbstractTransitionPrivate -{ - Q_DECLARE_PUBLIC(QEventTransition) -public: - QEventTransitionPrivate(); - - static QEventTransitionPrivate *get(QEventTransition *q); - - void invalidate(); - - bool registered; - QObject *object; - QEvent::Type eventType; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/corelib/statemachine/qfinalstate.cpp b/src/corelib/statemachine/qfinalstate.cpp deleted file mode 100644 index 0980336..0000000 --- a/src/corelib/statemachine/qfinalstate.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qfinalstate.h" -#include "qabstractstate_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QFinalState - - \brief The QFinalState class provides a final state. - - \since 4.6 - \ingroup statemachine - - A final state is used to communicate that (part of) a QStateMachine has - finished its work. When a final top-level state is entered, the state - machine's \l{QStateMachine::finished()}{finished}() signal is emitted. In - general, when a final substate (a child of a QState) is entered, the parent - state's \l{QState::finished()}{finished}() signal is emitted. QFinalState - is part of \l{The State Machine Framework}. - - To use a final state, you create a QFinalState object and add a transition - to it from another state. Example: - - \code - QPushButton button; - - QStateMachine machine; - QState *s1 = new QState(); - QFinalState *s2 = new QFinalState(); - s1->addTransition(&button, SIGNAL(clicked()), s2); - machine.addState(s1); - machine.addState(s2); - - QObject::connect(&machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit())); - machine.setInitialState(s1); - machine.start(); - \endcode - - \sa QStateMachine::finished(), QState::finished() -*/ - -class QFinalStatePrivate : public QAbstractStatePrivate -{ - Q_DECLARE_PUBLIC(QFinalState) - -public: - QFinalStatePrivate(); -}; - -QFinalStatePrivate::QFinalStatePrivate() -{ -} - -/*! - Constructs a new QFinalState object with the given \a parent state. -*/ -QFinalState::QFinalState(QState *parent) - : QAbstractState(*new QFinalStatePrivate, parent) -{ -} - -/*! - Destroys this final state. -*/ -QFinalState::~QFinalState() -{ -} - -/*! - \reimp -*/ -void QFinalState::onEntry(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \reimp -*/ -void QFinalState::onExit(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \reimp -*/ -bool QFinalState::event(QEvent *e) -{ - return QAbstractState::event(e); -} - -QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qfinalstate.h b/src/corelib/statemachine/qfinalstate.h deleted file mode 100644 index fa68394..0000000 --- a/src/corelib/statemachine/qfinalstate.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QFINALSTATE_H -#define QFINALSTATE_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QFinalStatePrivate; -class Q_CORE_EXPORT QFinalState : public QAbstractState -{ - Q_OBJECT -public: - QFinalState(QState *parent = 0); - ~QFinalState(); - -protected: - void onEntry(QEvent *event); - void onExit(QEvent *event); - - bool event(QEvent *e); - -private: - Q_DISABLE_COPY(QFinalState) - Q_DECLARE_PRIVATE(QFinalState) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/qhistorystate.cpp b/src/corelib/statemachine/qhistorystate.cpp deleted file mode 100644 index 517faa8..0000000 --- a/src/corelib/statemachine/qhistorystate.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qhistorystate.h" -#include "qhistorystate_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QHistoryState - - \brief The QHistoryState class provides a means of returning to a previously active substate. - - \since 4.6 - \ingroup statemachine - - A history state is a pseudo-state that represents the child state that the - parent state was in the last time the parent state was exited. A transition - with a history state as its target is in fact a transition to one of the - other child states of the parent state. QHistoryState is part of \l{The - State Machine Framework}. - - Use the setDefaultState() function to set the state that should be entered - if the parent state has never been entered. Example: - - \code - QStateMachine machine; - - QState *s1 = new QState(); - QState *s11 = new QState(s1); - QState *s12 = new QState(s1); - - QHistoryState *s1h = new QHistoryState(s1); - s1h->setDefaultState(s11); - - machine.addState(s1); - - QState *s2 = new QState(); - machine.addState(s2); - - QPushButton *button = new QPushButton(); - // Clicking the button will cause the state machine to enter the child state - // that s1 was in the last time s1 was exited, or the history state's default - // state if s1 has never been entered. - s1->addTransition(button, SIGNAL(clicked()), s1h); - \endcode - - By default a history state is shallow, meaning that it won't remember nested - states. This can be configured through the historyType property. -*/ - -/*! - \property QHistoryState::defaultState - - \brief the default state of this history state -*/ - -/*! - \property QHistoryState::historyType - - \brief the type of history that this history state records - - The default value of this property is QHistoryState::ShallowHistory. -*/ - -/*! - \enum QHistoryState::HistoryType - - This enum specifies the type of history that a QHistoryState records. - - \value ShallowHistory Only the immediate child states of the parent state - are recorded. In this case a transition with the history state as its - target will end up in the immediate child state that the parent was in the - last time it was exited. This is the default. - - \value DeepHistory Nested states are recorded. In this case a transition - with the history state as its target will end up in the most deeply nested - descendant state the parent was in the last time it was exited. -*/ - -QHistoryStatePrivate::QHistoryStatePrivate() - : defaultState(0) -{ -} - -QHistoryStatePrivate *QHistoryStatePrivate::get(QHistoryState *q) -{ - return q->d_func(); -} - -/*! - Constructs a new shallow history state with the given \a parent state. -*/ -QHistoryState::QHistoryState(QState *parent) - : QAbstractState(*new QHistoryStatePrivate, parent) -{ - Q_D(QHistoryState); - d->historyType = ShallowHistory; -} -/*! - Constructs a new history state of the given \a type, with the given \a - parent state. -*/ -QHistoryState::QHistoryState(HistoryType type, QState *parent) - : QAbstractState(*new QHistoryStatePrivate, parent) -{ - Q_D(QHistoryState); - d->historyType = type; -} - -/*! - Destroys this history state. -*/ -QHistoryState::~QHistoryState() -{ -} - -/*! - Returns this history state's default state. The default state indicates the - state to transition to if the parent state has never been entered before. -*/ -QAbstractState *QHistoryState::defaultState() const -{ - Q_D(const QHistoryState); - return d->defaultState; -} - -/*! - Sets this history state's default state to be the given \a state. - \a state must be a sibling of this history state. -*/ -void QHistoryState::setDefaultState(QAbstractState *state) -{ - Q_D(QHistoryState); - if (state && state->parentState() != parentState()) { - qWarning("QHistoryState::setDefaultState: state %p does not belong " - "to this history state's group (%p)", state, parentState()); - return; - } - d->defaultState = state; -} - -/*! - Returns the type of history that this history state records. -*/ -QHistoryState::HistoryType QHistoryState::historyType() const -{ - Q_D(const QHistoryState); - return d->historyType; -} - -/*! - Sets the \a type of history that this history state records. -*/ -void QHistoryState::setHistoryType(HistoryType type) -{ - Q_D(QHistoryState); - d->historyType = type; -} - -/*! - \reimp -*/ -void QHistoryState::onEntry(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \reimp -*/ -void QHistoryState::onExit(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \reimp -*/ -bool QHistoryState::event(QEvent *e) -{ - return QAbstractState::event(e); -} - -QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qhistorystate.h b/src/corelib/statemachine/qhistorystate.h deleted file mode 100644 index a0682bd..0000000 --- a/src/corelib/statemachine/qhistorystate.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QHISTORYSTATE_H -#define QHISTORYSTATE_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QHistoryStatePrivate; -class Q_CORE_EXPORT QHistoryState : public QAbstractState -{ - Q_OBJECT - Q_PROPERTY(QAbstractState* defaultState READ defaultState WRITE setDefaultState) - Q_PROPERTY(HistoryType historyType READ historyType WRITE setHistoryType) - Q_ENUMS(HistoryType) -public: - enum HistoryType { - ShallowHistory, - DeepHistory - }; - - QHistoryState(QState *parent = 0); - QHistoryState(HistoryType type, QState *parent = 0); - ~QHistoryState(); - - QAbstractState *defaultState() const; - void setDefaultState(QAbstractState *state); - - HistoryType historyType() const; - void setHistoryType(HistoryType type); - -protected: - void onEntry(QEvent *event); - void onExit(QEvent *event); - - bool event(QEvent *e); - -private: - Q_DISABLE_COPY(QHistoryState) - Q_DECLARE_PRIVATE(QHistoryState) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/qhistorystate_p.h b/src/corelib/statemachine/qhistorystate_p.h deleted file mode 100644 index 5aaa64c..0000000 --- a/src/corelib/statemachine/qhistorystate_p.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QHISTORYSTATE_P_H -#define QHISTORYSTATE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qabstractstate_p.h" - -#include - -QT_BEGIN_NAMESPACE - -class QHistoryState; -class QHistoryStatePrivate : public QAbstractStatePrivate -{ - Q_DECLARE_PUBLIC(QHistoryState) - -public: - QHistoryStatePrivate(); - - static QHistoryStatePrivate *get(QHistoryState *q); - - QAbstractState *defaultState; - QHistoryState::HistoryType historyType; - QList configuration; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/corelib/statemachine/qsignalevent.h b/src/corelib/statemachine/qsignalevent.h deleted file mode 100644 index 8221f68..0000000 --- a/src/corelib/statemachine/qsignalevent.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSIGNALEVENT_H -#define QSIGNALEVENT_H - -#include - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class Q_CORE_EXPORT QSignalEvent : public QEvent -{ -public: - QSignalEvent(const QObject *sender, int signalIndex, - const QList &arguments); - ~QSignalEvent(); - - inline const QObject *sender() const { return m_sender; } - inline int signalIndex() const { return m_signalIndex; } - inline QList arguments() const { return m_arguments; } - -private: - const QObject *m_sender; - int m_signalIndex; - QList m_arguments; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/qsignaleventgenerator_p.h b/src/corelib/statemachine/qsignaleventgenerator_p.h deleted file mode 100644 index cf0ea1e..0000000 --- a/src/corelib/statemachine/qsignaleventgenerator_p.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSIGNALEVENTGENERATOR_P_H -#define QSIGNALEVENTGENERATOR_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -class QStateMachine; - -class QSignalEventGenerator : public QObject -{ -public: - QSignalEventGenerator(QStateMachine *parent); - - static const QMetaObject staticMetaObject; - virtual const QMetaObject *metaObject() const; - virtual void *qt_metacast(const char *); - virtual int qt_metacall(QMetaObject::Call, int, void **argv); - -private: - Q_DISABLE_COPY(QSignalEventGenerator) -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp deleted file mode 100644 index 4caa917..0000000 --- a/src/corelib/statemachine/qsignaltransition.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsignaltransition.h" -#include "qsignaltransition_p.h" -#include "qsignalevent.h" -#include "qstate.h" -#include "qstate_p.h" -#include "qstatemachine.h" -#include "qstatemachine_p.h" -#include - -QT_BEGIN_NAMESPACE - -/*! - \class QSignalTransition - - \brief The QSignalTransition class provides a transition based on a Qt signal. - - \since 4.6 - \ingroup statemachine - - Typically you would use the overload of QState::addTransition() that takes a - sender and signal as arguments, rather than creating QSignalTransition - objects directly. QSignalTransition is part of \l{The State Machine - Framework}. - - You can subclass QSignalTransition and reimplement eventTest() to make a - signal transition conditional; the event object passed to eventTest() will - be a QSignalEvent object. Example: - - \code - class CheckedTransition : public QSignalTransition - { - public: - CheckedTransition(QCheckBox *check) - : QSignalTransition(check, SIGNAL(stateChanged(int))) {} - protected: - bool eventTest(QEvent *e) const { - if (!QSignalTransition::eventTest(e)) - return false; - QSignalEvent *se = static_cast(e); - return (se->arguments().at(0).toInt() == Qt::Checked); - } - }; - - ... - - QCheckBox *check = new QCheckBox(); - check->setTristate(true); - - QState *s1 = new QState(); - QState *s2 = new QState(); - CheckedTransition *t1 = new CheckedTransition(check); - t1->setTargetState(s2); - s1->addTransition(t1); - \endcode -*/ - -/*! - \property QSignalTransition::senderObject - - \brief the sender object that this signal transition is associated with -*/ - -/*! - \property QSignalTransition::signal - - \brief the signal that this signal transition is associated with -*/ - -QSignalTransitionPrivate::QSignalTransitionPrivate() -{ - sender = 0; - signalIndex = -1; -} - -QSignalTransitionPrivate *QSignalTransitionPrivate::get(QSignalTransition *q) -{ - return q->d_func(); -} - -void QSignalTransitionPrivate::invalidate() -{ - Q_Q(QSignalTransition); - if (signalIndex != -1) { - QState *source = sourceState(); - QStatePrivate *source_d = QStatePrivate::get(source); - QStateMachinePrivate *mach = QStateMachinePrivate::get(source_d->machine()); - if (mach) { - mach->unregisterSignalTransition(q); - if (mach->configuration.contains(source)) - mach->registerSignalTransition(q); - } - } -} - -/*! - Constructs a new signal transition with the given \a sourceState. -*/ -QSignalTransition::QSignalTransition(QState *sourceState) - : QAbstractTransition(*new QSignalTransitionPrivate, sourceState) -{ -} - -/*! - Constructs a new signal transition associated with the given \a signal of - the given \a sender, and with the given \a sourceState. -*/ -QSignalTransition::QSignalTransition(QObject *sender, const char *signal, - QState *sourceState) - : QAbstractTransition(*new QSignalTransitionPrivate, sourceState) -{ - Q_D(QSignalTransition); - d->sender = sender; - d->signal = signal; -} - -/*! - Constructs a new signal transition associated with the given \a signal of - the given \a sender. The transition has the given \a targets and \a - sourceState. -*/ -QSignalTransition::QSignalTransition(QObject *sender, const char *signal, - const QList &targets, - QState *sourceState) - : QAbstractTransition(*new QSignalTransitionPrivate, targets, sourceState) -{ - Q_D(QSignalTransition); - d->sender = sender; - d->signal = signal; -} - -/*! - Destroys this signal transition. -*/ -QSignalTransition::~QSignalTransition() -{ -} - -/*! - Returns the sender object associated with this signal transition. -*/ -QObject *QSignalTransition::senderObject() const -{ - Q_D(const QSignalTransition); - return d->sender; -} - -/*! - Sets the \a sender object associated with this signal transition. -*/ -void QSignalTransition::setSenderObject(QObject *sender) -{ - Q_D(QSignalTransition); - if (sender == d->sender) - return; - d->sender = sender; - d->invalidate(); -} - -/*! - Returns the signal associated with this signal transition. -*/ -QByteArray QSignalTransition::signal() const -{ - Q_D(const QSignalTransition); - return d->signal; -} - -/*! - Sets the \a signal associated with this signal transition. -*/ -void QSignalTransition::setSignal(const QByteArray &signal) -{ - Q_D(QSignalTransition); - if (signal == d->signal) - return; - d->signal = signal; - d->invalidate(); -} - -/*! - \reimp - - The \a event is a QSignalEvent object. The default implementation returns - true if the event's sender and signal index match this transition, and - returns false otherwise. -*/ -bool QSignalTransition::eventTest(QEvent *event) -{ - Q_D(const QSignalTransition); - if (event->type() == QEvent::Signal) { - if (d->signalIndex == -1) - return false; - QSignalEvent *se = static_cast(event); - return (se->sender() == d->sender) - && (se->signalIndex() == d->signalIndex); - } - return false; -} - -/*! - \reimp -*/ -void QSignalTransition::onTransition(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \reimp -*/ -bool QSignalTransition::event(QEvent *e) -{ - return QAbstractTransition::event(e); -} - -QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qsignaltransition.h b/src/corelib/statemachine/qsignaltransition.h deleted file mode 100644 index b485785..0000000 --- a/src/corelib/statemachine/qsignaltransition.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSIGNALTRANSITION_H -#define QSIGNALTRANSITION_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QSignalTransitionPrivate; -class Q_CORE_EXPORT QSignalTransition : public QAbstractTransition -{ - Q_OBJECT - Q_PROPERTY(QObject* senderObject READ senderObject WRITE setSenderObject) - Q_PROPERTY(QByteArray signal READ signal WRITE setSignal) -public: - QSignalTransition(QState *sourceState = 0); - QSignalTransition(QObject *sender, const char *signal, - QState *sourceState = 0); - QSignalTransition(QObject *sender, const char *signal, - const QList &targets, - QState *sourceState = 0); - ~QSignalTransition(); - - QObject *senderObject() const; - void setSenderObject(QObject *sender); - - QByteArray signal() const; - void setSignal(const QByteArray &signal); - -protected: - bool eventTest(QEvent *event); - void onTransition(QEvent *event); - - bool event(QEvent *e); - -private: - Q_DISABLE_COPY(QSignalTransition) - Q_DECLARE_PRIVATE(QSignalTransition) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/qsignaltransition_p.h b/src/corelib/statemachine/qsignaltransition_p.h deleted file mode 100644 index a23e58c..0000000 --- a/src/corelib/statemachine/qsignaltransition_p.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSIGNALTRANSITION_P_H -#define QSIGNALTRANSITION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qabstracttransition_p.h" - -QT_BEGIN_NAMESPACE - -class QSignalTransition; -class QSignalTransitionPrivate : public QAbstractTransitionPrivate -{ - Q_DECLARE_PUBLIC(QSignalTransition) -public: - QSignalTransitionPrivate(); - - static QSignalTransitionPrivate *get(QSignalTransition *q); - - void invalidate(); - - QObject *sender; - QByteArray signal; - int signalIndex; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp deleted file mode 100644 index e42e463..0000000 --- a/src/corelib/statemachine/qstate.cpp +++ /dev/null @@ -1,497 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qstate.h" -#include "qstate_p.h" -#include "qhistorystate.h" -#include "qhistorystate_p.h" -#include "qabstracttransition.h" -#include "qabstracttransition_p.h" -#include "qsignaltransition.h" -#include "qstatemachine.h" -#include "qstatemachine_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QState - - \brief The QState class provides a general-purpose state for QStateMachine. - - \since 4.6 - \ingroup statemachine - - QState objects can have child states, and can have transitions to other - states. QState is part of \l{The State Machine Framework}. - - The addTransition() function adds a transition. The removeTransition() - function removes a transition. - - The assignProperty() function is used for defining property assignments that - should be performed when a state is entered. - - Top-level states must be passed QStateMachine::rootState() as their parent - state, or added to a state machine using QStateMachine::addState(). - - \section1 States with Child States - - The childMode property determines how child states are treated. For - non-parallel state groups, the setInitialState() function must be called to - set the initial state. The child states are mutually exclusive states, and - the state machine needs to know which child state to enter when the parent - state is the target of a transition. - - The state emits the QState::finished() signal when a final child state - (QFinalState) is entered. - - The setErrorState() sets the state's error state. The error state is the - state that the state machine will transition to if an error is detected when - attempting to enter the state (e.g. because no initial state has been set). - -*/ - -/*! - \property QState::initialState - - \brief the initial state of this state (one of its child states) -*/ - -/*! - \property QState::errorState - - \brief the error state of this state -*/ - -/*! - \property QState::childMode - - \brief the child mode of this state - - The default value of this property is QState::ExclusiveStates. -*/ - -/*! - \enum QState::ChildMode - - This enum specifies how a state's child states are treated. - - \value ExclusiveStates The child states are mutually exclusive and an - initial state must be set by calling QState::setInitialState(). - - \value ParallelStates The child states are parallel. When the parent state - is entered, all its child states are entered in parallel. -*/ - -QStatePrivate::QStatePrivate() - : errorState(0), initialState(0), childMode(QState::ExclusiveStates) -{ -} - -QStatePrivate::~QStatePrivate() -{ -} - -QStatePrivate *QStatePrivate::get(QState *q) -{ - if (!q) - return 0; - return q->d_func(); -} - -const QStatePrivate *QStatePrivate::get(const QState *q) -{ - if (!q) - return 0; - return q->d_func(); -} - -void QStatePrivate::emitFinished() -{ - Q_Q(QState); - emit q->finished(); -} - -void QStatePrivate::emitPolished() -{ - Q_Q(QState); - emit q->polished(); -} - -/*! - Constructs a new state with the given \a parent state. -*/ -QState::QState(QState *parent) - : QAbstractState(*new QStatePrivate, parent) -{ -} - -/*! - Constructs a new state with the given \a childMode and the given \a parent - state. -*/ -QState::QState(ChildMode childMode, QState *parent) - : QAbstractState(*new QStatePrivate, parent) -{ - Q_D(QState); - d->childMode = childMode; -} - -/*! - \internal -*/ -QState::QState(QStatePrivate &dd, QState *parent) - : QAbstractState(dd, parent) -{ -} - -/*! - Destroys this state. -*/ -QState::~QState() -{ -} - -QList QStatePrivate::childStates() const -{ - QList result; - QList::const_iterator it; - for (it = children.constBegin(); it != children.constEnd(); ++it) { - QAbstractState *s = qobject_cast(*it); - if (!s || qobject_cast(s)) - continue; - result.append(s); - } - return result; -} - -QList QStatePrivate::historyStates() const -{ - QList result; - QList::const_iterator it; - for (it = children.constBegin(); it != children.constEnd(); ++it) { - QHistoryState *h = qobject_cast(*it); - if (h) - result.append(h); - } - return result; -} - -QList QStatePrivate::transitions() const -{ - QList result; - QList::const_iterator it; - for (it = children.constBegin(); it != children.constEnd(); ++it) { - QAbstractTransition *t = qobject_cast(*it); - if (t) - result.append(t); - } - return result; -} - -/*! - Instructs this state to set the property with the given \a name of the given - \a object to the given \a value when the state is entered. - - \sa polished() -*/ -void QState::assignProperty(QObject *object, const char *name, - const QVariant &value) -{ - Q_D(QState); - if (!object) { - qWarning("QState::assignProperty: cannot assign property '%s' of null object", name); - return; - } - for (int i = 0; i < d->propertyAssignments.size(); ++i) { - QPropertyAssignment &assn = d->propertyAssignments[i]; - if ((assn.object == object) && (assn.propertyName == name)) { - assn.value = value; - return; - } - } - d->propertyAssignments.append(QPropertyAssignment(object, name, value)); -} - -/*! - Returns this state group's error state. - - \sa QStateMachine::errorState(), QStateMachine::setErrorState() -*/ -QAbstractState *QState::errorState() const -{ - Q_D(const QState); - return d->errorState; -} - -/*! - Sets this state's error state to be the given \a state. If the error state - is not set, or if it is set to 0, the state will inherit its parent's error - state recursively. - - \sa QStateMachine::setErrorState(), QStateMachine::errorState() -*/ -void QState::setErrorState(QAbstractState *state) -{ - Q_D(QState); - if (state != 0 && state->machine() != machine()) { - qWarning("QState::setErrorState: error state cannot belong " - "to a different state machine"); - return; - } - if (state != 0 && state->machine() != 0 && state->machine()->rootState() == state) { - qWarning("QStateMachine::setErrorState: root state cannot be error state"); - return; - } - - d->errorState = state; -} - -/*! - Adds the given \a transition. The transition has this state as the source. - This state takes ownership of the transition. If the transition is successfully - added, the function will return the \a transition pointer. Otherwise it will return null. -*/ -QAbstractTransition *QState::addTransition(QAbstractTransition *transition) -{ - Q_D(QState); - if (!transition) { - qWarning("QState::addTransition: cannot add null transition"); - return 0; - } - - // machine() will always be non-null for root state - if (machine() != 0 && machine()->rootState() == this) { - qWarning("QState::addTransition: cannot add transition from root state"); - return 0; - } - - const QList > &targets = QAbstractTransitionPrivate::get(transition)->targetStates; - for (int i = 0; i < targets.size(); ++i) { - QAbstractState *t = targets.at(i); - if (!t) { - qWarning("QState::addTransition: cannot add transition to null state"); - return 0; - } - if ((QAbstractStatePrivate::get(t)->machine() != d->machine()) - && QAbstractStatePrivate::get(t)->machine() && d->machine()) { - qWarning("QState::addTransition: cannot add transition " - "to a state in a different state machine"); - return 0; - } - } - transition->setParent(this); - if (machine() != 0 && machine()->configuration().contains(this)) - QStateMachinePrivate::get(machine())->registerTransitions(this); - return transition; -} - -/*! - Adds a transition associated with the given \a signal of the given \a sender - object, and returns the new QSignalTransition object. The transition has - this state as the source, and the given \a target as the target state. -*/ -QSignalTransition *QState::addTransition(QObject *sender, const char *signal, - QAbstractState *target) -{ - if (!sender) { - qWarning("QState::addTransition: sender cannot be null"); - return 0; - } - if (!signal) { - qWarning("QState::addTransition: signal cannot be null"); - return 0; - } - if (!target) { - qWarning("QState::addTransition: cannot add transition to null state"); - return 0; - } - if (*signal && sender->metaObject()->indexOfSignal(signal+1) == -1) { - qWarning("QState::addTransition: no such signal %s::%s", - sender->metaObject()->className(), signal+1); - return 0; - } - QSignalTransition *trans = new QSignalTransition(sender, signal, QList() << target); - addTransition(trans); - return trans; -} - -namespace { - -// ### Make public? -class UnconditionalTransition : public QAbstractTransition -{ -public: - UnconditionalTransition(QAbstractState *target) - : QAbstractTransition(QList() << target) {} -protected: - void onTransition(QEvent *) {} - bool eventTest(QEvent *) { return true; } -}; - -} // namespace - -/*! - Adds an unconditional transition from this state to the given \a target - state, and returns then new transition object. -*/ -QAbstractTransition *QState::addTransition(QAbstractState *target) -{ - if (!target) { - qWarning("QState::addTransition: cannot add transition to null state"); - return 0; - } - UnconditionalTransition *trans = new UnconditionalTransition(target); - return addTransition(trans); -} - -/*! - Removes the given \a transition from this state. The state releases - ownership of the transition. - - \sa addTransition() -*/ -void QState::removeTransition(QAbstractTransition *transition) -{ - Q_D(QState); - if (!transition) { - qWarning("QState::removeTransition: cannot remove null transition"); - return; - } - if (transition->sourceState() != this) { - qWarning("QState::removeTransition: transition %p's source state (%p)" - " is different from this state (%p)", - transition, transition->sourceState(), this); - return; - } - QStateMachinePrivate *mach = QStateMachinePrivate::get(d->machine()); - if (mach) - mach->unregisterTransition(transition); - transition->setParent(0); -} - -/*! - \reimp -*/ -void QState::onEntry(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \reimp -*/ -void QState::onExit(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - Returns this state's initial state, or 0 if the state has no initial state. -*/ -QAbstractState *QState::initialState() const -{ - Q_D(const QState); - return d->initialState; -} - -/*! - Sets this state's initial state to be the given \a state. - \a state has to be a child of this state. -*/ -void QState::setInitialState(QAbstractState *state) -{ - Q_D(QState); - if (d->childMode == QState::ParallelStates) { - qWarning("QState::setInitialState: ignoring attempt to set initial state " - "of parallel state group %p", this); - return; - } - if (state && (state->parentState() != this)) { - qWarning("QState::setInitialState: state %p is not a child of this state (%p)", - state, this); - return; - } - d->initialState = state; -} - -/*! - Returns the child mode of this state. -*/ -QState::ChildMode QState::childMode() const -{ - Q_D(const QState); - return d->childMode; -} - -/*! - Sets the child \a mode of this state. -*/ -void QState::setChildMode(ChildMode mode) -{ - Q_D(QState); - d->childMode = mode; -} - -/*! - \reimp -*/ -bool QState::event(QEvent *e) -{ - return QAbstractState::event(e); -} - -/*! - \fn QState::finished() - - This signal is emitted when a final child state of this state is entered. - - \sa QFinalState -*/ - -/*! - \fn QState::polished() - - This signal is emitted when all properties have been assigned their final value. - - \sa QState::assignProperty(), QAbstractTransition::addAnimation() -*/ - -QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qstate.h b/src/corelib/statemachine/qstate.h deleted file mode 100644 index 6729c69..0000000 --- a/src/corelib/statemachine/qstate.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSTATE_H -#define QSTATE_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QAbstractTransition; -class QSignalTransition; - -class QStatePrivate; -class Q_CORE_EXPORT QState : public QAbstractState -{ - Q_OBJECT - Q_PROPERTY(QAbstractState* initialState READ initialState WRITE setInitialState) - Q_PROPERTY(QAbstractState* errorState READ errorState WRITE setErrorState) - Q_PROPERTY(ChildMode childMode READ childMode WRITE setChildMode) - Q_ENUMS(ChildMode) -public: - enum ChildMode { - ExclusiveStates, - ParallelStates - }; - - QState(QState *parent = 0); - QState(ChildMode childMode, QState *parent = 0); - ~QState(); - - QAbstractState *errorState() const; - void setErrorState(QAbstractState *state); - - QAbstractTransition *addTransition(QAbstractTransition *transition); - QSignalTransition *addTransition(QObject *sender, const char *signal, QAbstractState *target); - QAbstractTransition *addTransition(QAbstractState *target); - void removeTransition(QAbstractTransition *transition); - - QAbstractState *initialState() const; - void setInitialState(QAbstractState *state); - - ChildMode childMode() const; - void setChildMode(ChildMode mode); - - void assignProperty(QObject *object, const char *name, - const QVariant &value); - -Q_SIGNALS: - void finished(); - void polished(); - -protected: - void onEntry(QEvent *event); - void onExit(QEvent *event); - - bool event(QEvent *e); - -protected: - QState(QStatePrivate &dd, QState *parent); - -private: - Q_DISABLE_COPY(QState) - Q_DECLARE_PRIVATE(QState) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h deleted file mode 100644 index 1f913b4..0000000 --- a/src/corelib/statemachine/qstate_p.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSTATE_P_H -#define QSTATE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qabstractstate_p.h" - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -struct QPropertyAssignment -{ - QPropertyAssignment() - : object(0) {} - QPropertyAssignment(QObject *o, const QByteArray &n, - const QVariant &v, bool es = true) - : object(o), propertyName(n), value(v), explicitlySet(es) - {} - QObject *object; - QByteArray propertyName; - QVariant value; - bool explicitlySet; -}; - -class QAbstractTransition; -class QHistoryState; - -class QState; -class Q_CORE_EXPORT QStatePrivate : public QAbstractStatePrivate -{ - Q_DECLARE_PUBLIC(QState) -public: - QStatePrivate(); - ~QStatePrivate(); - - static QStatePrivate *get(QState *q); - static const QStatePrivate *get(const QState *q); - - QList childStates() const; - QList historyStates() const; - QList transitions() const; - - void emitFinished(); - void emitPolished(); - - QAbstractState *errorState; - QAbstractState *initialState; - QState::ChildMode childMode; - - QList propertyAssignments; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp deleted file mode 100644 index 744515b..0000000 --- a/src/corelib/statemachine/qstatemachine.cpp +++ /dev/null @@ -1,2216 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qstatemachine.h" -#include "qstate.h" -#include "qstate_p.h" -#include "qstatemachine_p.h" -#include "qabstracttransition.h" -#include "qabstracttransition_p.h" -#include "qsignaltransition.h" -#include "qsignaltransition_p.h" -#include "qsignalevent.h" -#include "qsignaleventgenerator_p.h" -#include "qabstractstate.h" -#include "qabstractstate_p.h" -#include "qfinalstate.h" -#include "qhistorystate.h" -#include "qhistorystate_p.h" -#include "private/qobject_p.h" -#include "private/qthread_p.h" - -#ifndef QT_NO_STATEMACHINE_EVENTFILTER -#include "qeventtransition.h" -#include "qeventtransition_p.h" -#include "qwrappedevent.h" -#endif - -#ifndef QT_NO_ANIMATION -#include "qpropertyanimation.h" -#include "qanimationgroup.h" -#include -#endif - -#include -#include - -QT_BEGIN_NAMESPACE - -/*! - \class QStateMachine - \reentrant - - \brief The QStateMachine class provides a hierarchical finite state machine. - - \since 4.6 - \ingroup statemachine - - QStateMachine is based on the concepts and notation of - \l{Statecharts: A visual formalism for complex - systems}{Statecharts}. QStateMachine is part of \l{The State - Machine Framework}. - - A state machine manages a set of states (classes that inherit from - QAbstractState) and transitions (descendants of - QAbstractTransition) between those states; these states and - transitions define a state graph. Once a state graph has been - built, the state machine can execute it. \l{QStateMachine}'s - execution algorithm is based on the \l{State Chart XML: State - Machine Notation for Control Abstraction}{State Chart XML (SCXML)} - algorithm. The framework's \l{The State Machine - Framework}{overview} gives several state graphs and the code to - build them. - - The rootState() is the parent of all top-level states in the - machine; it is used, for instance, when the state graph is - deleted. It is created by the machine. - - Use the addState() function to add a state to the state machine. - All top-level states are added to the root state. States are - removed with the removeState() function. Removing states while the - machine is running is discouraged. - - Before the machine can be started, the \l{initialState}{initial - state} must be set. The initial state is the state that the - machine enters when started. You can then start() the state - machine. The started() signal is emitted when the initial state is - entered. - - The machine is event driven and keeps its own event loop. Events - are posted to the machine through postEvent(). Note that this - means that it executes asynchronously, and that it will not - progress without a running event loop. You will normally not have - to post events to the machine directly as Qt's transitions, e.g., - QEventTransition and its subclasses, handle this. But for custom - transitions triggered by events, postEvent() is useful. - - The state machine processes events and takes transitions until a - top-level final state is entered; the state machine then emits the - finished() signal. You can also stop() the state machine - explicitly. The stopped() signal is emitted in this case. - - The following snippet shows a state machine that will finish when a button - is clicked: - - \code - QPushButton button; - - QStateMachine machine; - QState *s1 = new QState(); - s1->assignProperty(&button, "text", "Click me"); - - QFinalState *s2 = new QFinalState(); - s1->addTransition(&button, SIGNAL(clicked()), s2); - - machine.addState(s1); - machine.addState(s2); - machine.setInitialState(s1); - machine.start(); - \endcode - - This code example uses QState, which inherits QAbstractState. The - QState class provides a state that you can use to set properties - and invoke methods on \l{QObject}s when the state is entered or - exited. It also contains convenience functions for adding - transitions, e.g., \l{QSignalTransition}s as in this example. See - the QState class description for further details. - - If an error is encountered, the machine will enter the - \l{errorState}{error state}, which is a special state created by - the machine. The types of errors possible are described by the - \l{QStateMachine::}{Error} enum. After the error state is entered, - the type of the error can be retrieved with error(). The execution - of the state graph will not stop when the error state is entered. - So it is possible to handle the error, for instance, by connecting - to the \l{QAbstractState::}{entered()} signal of the error state. - It is also possible to set a custom error state with - setErrorState(). - - \omit This stuff will be moved elsewhere -This is - typically used in conjunction with \l{Signals and Slots}{signals}; the - signals determine the flow of the state graph, whereas the states' property - assignments and method invocations are the actions. - - The postEvent() function posts an event to the state machine. This is useful - when you are using custom events to trigger transitions. - \endomit - - \sa QAbstractState, QAbstractTransition, QState, {The State Machine Framework} -*/ - -/*! - \property QStateMachine::rootState - - \brief the root state of this state machine -*/ - -/*! - \property QStateMachine::initialState - - \brief the initial state of this state machine - - The initial state must be one of the rootState()'s child states. -*/ - -/*! - \property QStateMachine::errorState - - \brief the error state of this state machine -*/ - -/*! - \property QStateMachine::errorString - - \brief the error string of this state machine -*/ - -/*! - \property QStateMachine::globalRestorePolicy - - \brief the restore policy for states of this state machine. - - The default value of this property is - QStateMachine::DoNotRestoreProperties. -*/ - -#ifndef QT_NO_ANIMATION -/*! - \property QStateMachine::animationsEnabled - - \brief whether animations are enabled - - The default value of this property is true. - - \sa QAbstractTransition::addAnimation() -*/ -#endif - -// #define QSTATEMACHINE_DEBUG - -QStateMachinePrivate::QStateMachinePrivate() -{ - state = NotRunning; - processing = false; - processingScheduled = false; - stop = false; - error = QStateMachine::NoError; - globalRestorePolicy = QStateMachine::DoNotRestoreProperties; - rootState = 0; - initialErrorStateForRoot = 0; - signalEventGenerator = 0; -#ifndef QT_NO_ANIMATION - animationsEnabled = true; -#endif -} - -QStateMachinePrivate::~QStateMachinePrivate() -{ - qDeleteAll(internalEventQueue); - qDeleteAll(externalEventQueue); -} - -QStateMachinePrivate *QStateMachinePrivate::get(QStateMachine *q) -{ - if (q) - return q->d_func(); - return 0; -} - -static QEvent *cloneEvent(QEvent *e) -{ - switch (e->type()) { - case QEvent::None: - return new QEvent(*e); - case QEvent::Timer: - return new QTimerEvent(*static_cast(e)); - default: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - } - return 0; -} - -const QStateMachinePrivate::Handler qt_kernel_statemachine_handler = { - cloneEvent -}; - -const QStateMachinePrivate::Handler *QStateMachinePrivate::handler = &qt_kernel_statemachine_handler; - -Q_CORE_EXPORT const QStateMachinePrivate::Handler *qcoreStateMachineHandler() -{ - return &qt_kernel_statemachine_handler; -} - -static int indexOfDescendant(QState *s, QAbstractState *desc) -{ - QList childStates = QStatePrivate::get(s)->childStates(); - for (int i = 0; i < childStates.size(); ++i) { - QAbstractState *c = childStates.at(i); - if ((c == desc) || QStateMachinePrivate::isDescendantOf(desc, c)) { - return i; - } - } - return -1; -} - -bool QStateMachinePrivate::stateEntryLessThan(QAbstractState *s1, QAbstractState *s2) -{ - if (s1->parent() == s2->parent()) { - return s1->children().indexOf(s1) - < s2->children().indexOf(s2); - } else if (isDescendantOf(s1, s2)) { - return false; - } else if (isDescendantOf(s2, s1)) { - return true; - } else { - QState *lca = findLCA(QList() << s1 << s2); - Q_ASSERT(lca != 0); - return (indexOfDescendant(lca, s1) < indexOfDescendant(lca, s2)); - } -} - -bool QStateMachinePrivate::stateExitLessThan(QAbstractState *s1, QAbstractState *s2) -{ - if (s1->parent() == s2->parent()) { - return s1->children().indexOf(s1) - < s2->children().indexOf(s2); - } else if (isDescendantOf(s1, s2)) { - return true; - } else if (isDescendantOf(s2, s1)) { - return false; - } else { - QState *lca = findLCA(QList() << s1 << s2); - Q_ASSERT(lca != 0); - return (indexOfDescendant(lca, s1) < indexOfDescendant(lca, s2)); - } -} - -QState *QStateMachinePrivate::findLCA(const QList &states) -{ - if (states.isEmpty()) - return 0; - QList ancestors = properAncestors(states.at(0), 0); - for (int i = 0; i < ancestors.size(); ++i) { - QState *anc = ancestors.at(i); - bool ok = true; - for (int j = states.size() - 1; (j > 0) && ok; --j) { - const QAbstractState *s = states.at(j); - if (!isDescendantOf(s, anc)) - ok = false; - } - if (ok) - return anc; - } - return 0; -} - -bool QStateMachinePrivate::isPreempted(const QAbstractState *s, const QSet &transitions) const -{ - QSet::const_iterator it; - for (it = transitions.constBegin(); it != transitions.constEnd(); ++it) { - QAbstractTransition *t = *it; - QList lst = t->targetStates(); - if (!lst.isEmpty()) { - lst.prepend(t->sourceState()); - QAbstractState *lca = findLCA(lst); - if (isDescendantOf(s, lca)) { -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ":" << transitions << "preempts selection of a transition from" - << s << "because" << s << "is a descendant of" << lca; -#endif - return true; - } - } - } - return false; -} - -QSet QStateMachinePrivate::selectTransitions(QEvent *event) const -{ - Q_Q(const QStateMachine); - QSet enabledTransitions; - QSet::const_iterator it; - const_cast(q)->beginSelectTransitions(event); - for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { - QAbstractState *state = *it; - if (!isAtomic(state)) - continue; - if (isPreempted(state, enabledTransitions)) - continue; - QList lst = properAncestors(state, 0); - if (QState *grp = qobject_cast(state)) - lst.prepend(grp); - bool found = false; - for (int j = 0; (j < lst.size()) && !found; ++j) { - QState *s = lst.at(j); - QList transitions = QStatePrivate::get(s)->transitions(); - for (int k = 0; k < transitions.size(); ++k) { - QAbstractTransition *t = transitions.at(k); - if (QAbstractTransitionPrivate::get(t)->callEventTest(event)) { -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": selecting transition" << t; -#endif - enabledTransitions.insert(t); - found = true; - break; - } - } - } - } - const_cast(q)->endSelectTransitions(event); - return enabledTransitions; -} - -void QStateMachinePrivate::microstep(QEvent *event, const QList &enabledTransitions) -{ -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": begin microstep( enabledTransitions:" << enabledTransitions << ")"; - qDebug() << q_func() << ": configuration before exiting states:" << configuration; -#endif - QList exitedStates = exitStates(event, enabledTransitions); -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": configuration after exiting states:" << configuration; -#endif - executeTransitionContent(event, enabledTransitions); - QList enteredStates = enterStates(event, enabledTransitions); - applyProperties(enabledTransitions, exitedStates, enteredStates); -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": configuration after entering states:" << configuration; - qDebug() << q_func() << ": end microstep"; -#endif -} - -QList QStateMachinePrivate::exitStates(QEvent *event, const QList &enabledTransitions) -{ -// qDebug() << "exitStates(" << enabledTransitions << ")"; - QSet statesToExit; -// QSet statesToSnapshot; - for (int i = 0; i < enabledTransitions.size(); ++i) { - QAbstractTransition *t = enabledTransitions.at(i); - QList lst = t->targetStates(); - if (lst.isEmpty()) - continue; - lst.prepend(t->sourceState()); - QAbstractState *lca = findLCA(lst); - if (lca == 0) { - setError(QStateMachine::NoCommonAncestorForTransitionError, t->sourceState()); - lst = pendingErrorStates.toList(); - lst.prepend(t->sourceState()); - - lca = findLCA(lst); - Q_ASSERT(lca != 0); - } - - { - QSet::const_iterator it; - for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { - QAbstractState *s = *it; - if (isDescendantOf(s, lca)) - statesToExit.insert(s); - } - } - } - QList statesToExit_sorted = statesToExit.toList(); - qSort(statesToExit_sorted.begin(), statesToExit_sorted.end(), stateExitLessThan); - for (int i = 0; i < statesToExit_sorted.size(); ++i) { - QAbstractState *s = statesToExit_sorted.at(i); - if (QState *grp = qobject_cast(s)) { - QList hlst = QStatePrivate::get(grp)->historyStates(); - for (int j = 0; j < hlst.size(); ++j) { - QHistoryState *h = hlst.at(j); - QHistoryStatePrivate::get(h)->configuration.clear(); - QSet::const_iterator it; - for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { - QAbstractState *s0 = *it; - if (QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) { - if (isAtomic(s0) && isDescendantOf(s0, s)) - QHistoryStatePrivate::get(h)->configuration.append(s0); - } else if (s0->parentState() == s) { - QHistoryStatePrivate::get(h)->configuration.append(s0); - } - } -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": recorded" << ((QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) ? "deep" : "shallow") - << "history for" << s << "in" << h << ":" << QHistoryStatePrivate::get(h)->configuration; -#endif - } - } - } - for (int i = 0; i < statesToExit_sorted.size(); ++i) { - QAbstractState *s = statesToExit_sorted.at(i); -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": exiting" << s; -#endif - QAbstractStatePrivate::get(s)->callOnExit(event); - configuration.remove(s); - QAbstractStatePrivate::get(s)->emitExited(); - } - return statesToExit_sorted; -} - -void QStateMachinePrivate::executeTransitionContent(QEvent *event, const QList &enabledTransitions) -{ - for (int i = 0; i < enabledTransitions.size(); ++i) { - QAbstractTransition *t = enabledTransitions.at(i); -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": triggering" << t; -#endif - QAbstractTransitionPrivate::get(t)->callOnTransition(event); - } -} - -QList QStateMachinePrivate::enterStates(QEvent *event, const QList &enabledTransitions) -{ -#ifdef QSTATEMACHINE_DEBUG - Q_Q(QStateMachine); -#endif -// qDebug() << "enterStates(" << enabledTransitions << ")"; - QSet statesToEnter; - QSet statesForDefaultEntry; - - if (pendingErrorStates.isEmpty()) { - for (int i = 0; i < enabledTransitions.size(); ++i) { - QAbstractTransition *t = enabledTransitions.at(i); - QList lst = t->targetStates(); - if (lst.isEmpty()) - continue; - lst.prepend(t->sourceState()); - QState *lca = findLCA(lst); - for (int j = 1; j < lst.size(); ++j) { - QAbstractState *s = lst.at(j); - addStatesToEnter(s, lca, statesToEnter, statesForDefaultEntry); - if (isParallel(lca)) { - QList lcac = QStatePrivate::get(lca)->childStates(); - foreach (QAbstractState* child,lcac) { - if (!statesToEnter.contains(child)) - addStatesToEnter(child,lca,statesToEnter,statesForDefaultEntry); - } - } - } - } - } - - // Did an error occur while selecting transitions? Then we enter the error state. - if (!pendingErrorStates.isEmpty()) { - statesToEnter.clear(); - statesToEnter = pendingErrorStates; - statesForDefaultEntry = pendingErrorStatesForDefaultEntry; - pendingErrorStates.clear(); - pendingErrorStatesForDefaultEntry.clear(); - } - - QList statesToEnter_sorted = statesToEnter.toList(); - qSort(statesToEnter_sorted.begin(), statesToEnter_sorted.end(), stateEntryLessThan); - - for (int i = 0; i < statesToEnter_sorted.size(); ++i) { - QAbstractState *s = statesToEnter_sorted.at(i); -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": entering" << s; -#endif - configuration.insert(s); - registerTransitions(s); - QAbstractStatePrivate::get(s)->callOnEntry(event); - QAbstractStatePrivate::get(s)->emitEntered(); - if (statesForDefaultEntry.contains(s)) { - // ### executeContent(s.initial.transition.children()) - } - if (isFinal(s)) { - QState *parent = s->parentState(); - if (parent) { - QState *grandparent = parent->parentState(); -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": emitting finished signal for" << parent; -#endif - QStatePrivate::get(parent)->emitFinished(); - if (grandparent && isParallel(grandparent)) { - bool allChildStatesFinal = true; - QList childStates = QStatePrivate::get(grandparent)->childStates(); - for (int j = 0; j < childStates.size(); ++j) { - QAbstractState *cs = childStates.at(j); - if (!isInFinalState(cs)) { - allChildStatesFinal = false; - break; - } - } - if (allChildStatesFinal) { -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": emitting finished signal for" << grandparent; -#endif - QStatePrivate::get(grandparent)->emitFinished(); - } - } - } - } - } - { - QSet::const_iterator it; - for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { - if (isFinal(*it) && (*it)->parentState() == rootState) { - processing = false; - stopProcessingReason = Finished; - break; - } - } - } -// qDebug() << "configuration:" << configuration.toList(); - return statesToEnter_sorted; -} - -void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, - QSet &statesToEnter, - QSet &statesForDefaultEntry) -{ - if (QHistoryState *h = qobject_cast(s)) { - QList hconf = QHistoryStatePrivate::get(h)->configuration; - if (!hconf.isEmpty()) { - for (int k = 0; k < hconf.size(); ++k) { - QAbstractState *s0 = hconf.at(k); - addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry); - } - #ifdef QSTATEMACHINE_DEBUG - qDebug() <historyType == QHistoryState::DeepHistory) ? "deep" : "shallow") - << "history from" << s << ":" << hconf; - #endif - } else { - QList hlst; - if (QHistoryStatePrivate::get(h)->defaultState) - hlst.append(QHistoryStatePrivate::get(h)->defaultState); - - if (hlst.isEmpty()) { - setError(QStateMachine::NoDefaultStateInHistoryStateError, h); - } else { - for (int k = 0; k < hlst.size(); ++k) { - QAbstractState *s0 = hlst.at(k); - addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry); - } - #ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": initial history targets for" << s << ":" << hlst; - #endif - } - } - } else { - statesToEnter.insert(s); - if (isParallel(s)) { - QState *grp = qobject_cast(s); - QList lst = QStatePrivate::get(grp)->childStates(); - for (int i = 0; i < lst.size(); ++i) { - QAbstractState *child = lst.at(i); - addStatesToEnter(child, grp, statesToEnter, statesForDefaultEntry); - } - } else if (isCompound(s)) { - statesForDefaultEntry.insert(s); - QState *grp = qobject_cast(s); - QAbstractState *initial = grp->initialState(); - if (initial != 0) { - addStatesToEnter(initial, grp, statesToEnter, statesForDefaultEntry); - } else { - setError(QStateMachine::NoInitialStateError, grp); - return; - } - } - QList ancs = properAncestors(s, root); - for (int i = 0; i < ancs.size(); ++i) { - QState *anc = ancs.at(i); - if (!anc->parentState()) - continue; - statesToEnter.insert(anc); - if (isParallel(anc)) { - QList lst = QStatePrivate::get(anc)->childStates(); - for (int j = 0; j < lst.size(); ++j) { - QAbstractState *child = lst.at(j); - bool hasDescendantInList = false; - QSet::const_iterator it; - for (it = statesToEnter.constBegin(); it != statesToEnter.constEnd(); ++it) { - if (isDescendantOf(*it, child)) { - hasDescendantInList = true; - break; - } - } - if (!hasDescendantInList) - addStatesToEnter(child, anc, statesToEnter, statesForDefaultEntry); - } - } - } - } -} - -void QStateMachinePrivate::applyProperties(const QList &transitionList, - const QList &exitedStates, - const QList &enteredStates) -{ - Q_Q(QStateMachine); -#ifdef QT_NO_ANIMATION - Q_UNUSED(transitionList); -#endif - // Process the property assignments of the entered states. - QHash > propertyAssignmentsForState; - QHash pendingRestorables = registeredRestorables; - for (int i = 0; i < enteredStates.size(); ++i) { - QState *s = qobject_cast(enteredStates.at(i)); - if (!s) - continue; - - QList assignments = QStatePrivate::get(s)->propertyAssignments; - for (int j = 0; j < assignments.size(); ++j) { - const QPropertyAssignment &assn = assignments.at(j); - if (globalRestorePolicy == QStateMachine::RestoreProperties) { - registerRestorable(assn.object, assn.propertyName); - } - pendingRestorables.remove(RestorableId(assn.object, assn.propertyName)); - propertyAssignmentsForState[s].append(assn); - } - - // Remove pending restorables for all parent states to avoid restoring properties - // before the state that assigned them is exited. If state does not explicitly - // assign a property which is assigned by the parent, it inherits the parent's assignment. - QState *parentState = s; - while ((parentState = parentState->parentState()) != 0) { - assignments = QStatePrivate::get(parentState)->propertyAssignments; - for (int j=0; j 0) - propertyAssignmentsForState[s].append(assn); - } - } - } - if (!pendingRestorables.isEmpty()) { - QAbstractState *s; - if (!enteredStates.isEmpty()) - s = enteredStates.last(); // ### handle if parallel - else - s = 0; - propertyAssignmentsForState[s] << restorablesToPropertyList(pendingRestorables); - } - -#ifndef QT_NO_ANIMATION - // Gracefully terminate playing animations for states that are exited. - for (int i = 0; i < exitedStates.size(); ++i) { - QAbstractState *s = exitedStates.at(i); - QList animations = animationsForState.take(s); - for (int j = 0; j < animations.size(); ++j) { - QAbstractAnimation *anim = animations.at(j); - QObject::disconnect(anim, SIGNAL(finished()), q, SLOT(_q_animationFinished())); - stateForAnimation.remove(anim); - - // Stop the (top-level) animation. - // ### Stopping nested animation has weird behavior. - QAbstractAnimation *topLevelAnim = anim; - while (QAnimationGroup *group = topLevelAnim->group()) - topLevelAnim = group; - topLevelAnim->stop(); - - if (resetAnimationEndValues.contains(anim)) { - qobject_cast(anim)->setEndValue(QVariant()); // ### generalize - resetAnimationEndValues.remove(anim); - } - QPropertyAssignment assn = propertyForAnimation.take(anim); - Q_ASSERT(assn.object != 0); - // If there is no property assignment that sets this property, - // set the property to its target value. - bool found = false; - QHash >::const_iterator it; - for (it = propertyAssignmentsForState.constBegin(); it != propertyAssignmentsForState.constEnd(); ++it) { - const QList &assignments = it.value(); - for (int k = 0; k < assignments.size(); ++k) { - if ((assignments.at(k).object == assn.object) - && (assignments.at(k).propertyName == assn.propertyName)) { - found = true; - break; - } - } - } - if (!found) { - assn.object->setProperty(assn.propertyName, assn.value); - } - } - } - - // Find the animations to use for the state change. - QList selectedAnimations; - if (animationsEnabled) { - for (int i = 0; i < transitionList.size(); ++i) { - QAbstractTransition *transition = transitionList.at(i); - - selectedAnimations << transition->animations(); - selectedAnimations << defaultAnimationsForSource.values(transition->sourceState()); - - QList targetStates = transition->targetStates(); - for (int j=0; j >::iterator it; - for (it = propertyAssignmentsForState.begin(); it != propertyAssignmentsForState.end(); ) { - QList::iterator it2; - QAbstractState *s = it.key(); - QList &assignments = it.value(); - for (it2 = assignments.begin(); it2 != assignments.end(); ) { - QPair, QList > ret; - ret = initializeAnimation(anim, *it2); - QList handlers = ret.first; - if (!handlers.isEmpty()) { - for (int j = 0; j < handlers.size(); ++j) { - QAbstractAnimation *a = handlers.at(j); - propertyForAnimation.insert(a, *it2); - stateForAnimation.insert(a, s); - animationsForState[s].append(a); - // ### connect to just the top-level animation? - QObject::disconnect(a, SIGNAL(finished()), q, SLOT(_q_animationFinished())); - QObject::connect(a, SIGNAL(finished()), q, SLOT(_q_animationFinished())); - } - it2 = assignments.erase(it2); - } else { - ++it2; - } - for (int j = 0; j < ret.second.size(); ++j) - resetAnimationEndValues.insert(ret.second.at(j)); - } - if (assignments.isEmpty()) - it = propertyAssignmentsForState.erase(it); - else - ++it; - } - // We require that at least one animation is valid. - // ### generalize - QList variantAnims = qFindChildren(anim); - if (QVariantAnimation *va = qobject_cast(anim)) - variantAnims.append(va); - - bool hasValidEndValue = false; - for (int j = 0; j < variantAnims.size(); ++j) { - if (variantAnims.at(j)->endValue().isValid()) { - hasValidEndValue = true; - break; - } - } - - if (hasValidEndValue) { - anim->start(); - } - } -#endif // !QT_NO_ANIMATION - - // Immediately set the properties that are not animated. - { - QHash >::const_iterator it; - for (it = propertyAssignmentsForState.constBegin(); it != propertyAssignmentsForState.constEnd(); ++it) { - const QList &assignments = it.value(); - for (int i = 0; i < assignments.size(); ++i) { - const QPropertyAssignment &assn = assignments.at(i); - assn.object->setProperty(assn.propertyName, assn.value); - } - } - } - - // Emit polished signal for entered states that have no animated properties. - for (int i = 0; i < enteredStates.size(); ++i) { - QState *s = qobject_cast(enteredStates.at(i)); - if (s && !animationsForState.contains(s)) - QStatePrivate::get(s)->emitPolished(); - } -} - -bool QStateMachinePrivate::isFinal(const QAbstractState *s) -{ - return qobject_cast(s) != 0; -} - -bool QStateMachinePrivate::isParallel(const QAbstractState *s) -{ - const QState *ss = qobject_cast(s); - return ss && (QStatePrivate::get(ss)->childMode == QState::ParallelStates); -} - -bool QStateMachinePrivate::isCompound(const QAbstractState *s) -{ - const QState *group = qobject_cast(s); - if (!group) - return false; - return (!isParallel(group) && !QStatePrivate::get(group)->childStates().isEmpty()) - || (qobject_cast(group->parent()) != 0); -} - -bool QStateMachinePrivate::isAtomic(const QAbstractState *s) -{ - const QState *ss = qobject_cast(s); - return (ss && QStatePrivate::get(ss)->childStates().isEmpty()) - || isFinal(s); -} - - -bool QStateMachinePrivate::isDescendantOf(const QAbstractState *state, const QAbstractState *other) -{ - Q_ASSERT(state != 0); - for (QAbstractState *s = state->parentState(); s != 0; s = s->parentState()) { - if (s == other) - return true; - } - return false; -} - -QList QStateMachinePrivate::properAncestors(const QAbstractState *state, const QState *upperBound) -{ - Q_ASSERT(state != 0); - QList result; - for (QState *s = state->parentState(); s && s != upperBound; s = s->parentState()) { - result.append(s); - } - return result; -} - -bool QStateMachinePrivate::isInFinalState(QAbstractState* s) const -{ - if (isCompound(s)) { - QState *grp = qobject_cast(s); - QList lst = QStatePrivate::get(grp)->childStates(); - for (int i = 0; i < lst.size(); ++i) { - QAbstractState *cs = lst.at(i); - if (isFinal(cs) && configuration.contains(cs)) - return true; - } - return false; - } else if (isParallel(s)) { - QState *grp = qobject_cast(s); - QList lst = QStatePrivate::get(grp)->childStates(); - for (int i = 0; i < lst.size(); ++i) { - QAbstractState *cs = lst.at(i); - if (!isInFinalState(cs)) - return false; - } - return true; - } - else - return false; -} - -void QStateMachinePrivate::registerRestorable(QObject *object, const QByteArray &propertyName) -{ - RestorableId id(object, propertyName); - if (!registeredRestorables.contains(id)) - registeredRestorables.insert(id, object->property(propertyName)); -} - -QList QStateMachinePrivate::restorablesToPropertyList(const QHash &restorables) const -{ - QList result; - QHash::const_iterator it; - for (it = restorables.constBegin(); it != restorables.constEnd(); ++it) { -// qDebug() << "restorable:" << it.key().first << it.key().second << it.value(); - result.append(QPropertyAssignment(it.key().first, it.key().second, it.value(), /*explicitlySet=*/false)); - } - return result; -} - -/*! - \internal - Returns true if the variable with the given \a id has been registered for restoration. -*/ -bool QStateMachinePrivate::hasRestorable(QObject *object, const QByteArray &propertyName) const -{ - return registeredRestorables.contains(RestorableId(object, propertyName)); -} - -QVariant QStateMachinePrivate::restorableValue(QObject *object, const QByteArray &propertyName) const -{ - return registeredRestorables.value(RestorableId(object, propertyName), QVariant()); -} - - -/*! - \internal - Unregisters the variable identified by \a id -*/ -void QStateMachinePrivate::unregisterRestorable(QObject *object, const QByteArray &propertyName) -{ -// qDebug() << "unregisterRestorable(" << object << propertyName << ")"; - RestorableId id(object, propertyName); - registeredRestorables.remove(id); -} - -QAbstractState *QStateMachinePrivate::findErrorState(QAbstractState *context) -{ - // If the user sets the root state's error state to 0, we return the initial error state - if (context == 0) - return initialErrorStateForRoot; - - // Find error state recursively in parent hierarchy if not set explicitly for context state - QAbstractState *errorState = 0; - - QState *s = qobject_cast(context); - if (s) - errorState = s->errorState(); - - if (!errorState) - errorState = findErrorState(context->parentState()); - - return errorState; -} - -void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractState *currentContext) -{ - error = errorCode; - - switch (errorCode) { - case QStateMachine::NoInitialStateError: - Q_ASSERT(currentContext != 0); - - errorString = QStateMachine::tr("Missing initial state in compound state '%1'") - .arg(currentContext->objectName()); - - break; - case QStateMachine::NoDefaultStateInHistoryStateError: - Q_ASSERT(currentContext != 0); - - errorString = QStateMachine::tr("Missing default state in history state '%1'") - .arg(currentContext->objectName()); - break; - - case QStateMachine::NoCommonAncestorForTransitionError: - Q_ASSERT(currentContext != 0); - - errorString = QStateMachine::tr("No common ancestor for targets and source of transition from state '%1'") - .arg(currentContext->objectName()); - break; - default: - errorString = QStateMachine::tr("Unknown error"); - }; - - pendingErrorStates.clear(); - pendingErrorStatesForDefaultEntry.clear(); - - QAbstractState *currentErrorState = findErrorState(currentContext); - - // Avoid infinite loop if the error state itself has an error - if (currentContext == currentErrorState) { - Q_ASSERT(currentContext != initialErrorStateForRoot); // RootErrorState is broken - currentErrorState = initialErrorStateForRoot; - } - - Q_ASSERT(currentErrorState != 0); - Q_ASSERT(currentErrorState != rootState); - - QState *lca = findLCA(QList() << currentErrorState << currentContext); - addStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry); -} - -#ifndef QT_NO_ANIMATION - -QPair, QList > -QStateMachinePrivate::initializeAnimation(QAbstractAnimation *abstractAnimation, - const QPropertyAssignment &prop) -{ - QList handledAnimations; - QList localResetEndValues; - QAnimationGroup *group = qobject_cast(abstractAnimation); - if (group) { - for (int i = 0; i < group->animationCount(); ++i) { - QAbstractAnimation *animationChild = group->animationAt(i); - QPair, QList > ret; - ret = initializeAnimation(animationChild, prop); - handledAnimations << ret.first; - localResetEndValues << ret.second; - } - } else { - QPropertyAnimation *animation = qobject_cast(abstractAnimation); - if (animation != 0 - && prop.object == animation->targetObject() - && prop.propertyName == animation->propertyName()) { - - // Only change end value if it is undefined - if (!animation->endValue().isValid()) { - animation->setEndValue(prop.value); - localResetEndValues.append(animation); - } - handledAnimations.append(animation); - } - } - return qMakePair(handledAnimations, localResetEndValues); -} - -void QStateMachinePrivate::_q_animationFinished() -{ - Q_Q(QStateMachine); - QAbstractAnimation *anim = qobject_cast(q->sender()); - Q_ASSERT(anim != 0); - QObject::disconnect(anim, SIGNAL(finished()), q, SLOT(_q_animationFinished())); - if (resetAnimationEndValues.contains(anim)) { - qobject_cast(anim)->setEndValue(QVariant()); // ### generalize - resetAnimationEndValues.remove(anim); - } - - // Set the final property value. - QPropertyAssignment assn = propertyForAnimation.take(anim); - Q_ASSERT(assn.object != 0); - assn.object->setProperty(assn.propertyName, assn.value); - if (!assn.explicitlySet) - unregisterRestorable(assn.object, assn.propertyName); - - QAbstractState *state = stateForAnimation.take(anim); - Q_ASSERT(state != 0); - QHash >::iterator it; - it = animationsForState.find(state); - Q_ASSERT(it != animationsForState.end()); - QList &animations = it.value(); - animations.removeOne(anim); - if (animations.isEmpty()) { - animationsForState.erase(it); - QStatePrivate::get(qobject_cast(state))->emitPolished(); - } -} - -#endif // !QT_NO_ANIMATION - -namespace { - -class StartState : public QState -{ -public: - StartState(QState *parent) - : QState(parent) {} -protected: - void onEntry(QEvent *) {} - void onExit(QEvent *) {} -}; - -class InitialTransition : public QAbstractTransition -{ -public: - InitialTransition(QAbstractState *target) - : QAbstractTransition(QList() << target) {} -protected: - virtual bool eventTest(QEvent *) { return true; } - virtual void onTransition(QEvent *) {} -}; - -} // namespace - -void QStateMachinePrivate::_q_start() -{ - Q_Q(QStateMachine); - Q_ASSERT(state == Starting); - if (!rootState) { - state = NotRunning; - return; - } - QAbstractState *initial = rootState->initialState(); - if (initial == 0) - setError(QStateMachine::NoInitialStateError, rootState); - - configuration.clear(); - qDeleteAll(internalEventQueue); - internalEventQueue.clear(); - qDeleteAll(externalEventQueue); - externalEventQueue.clear(); - -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": starting"; -#endif - state = Running; - processingScheduled = true; // we call _q_process() below - emit q->started(); - - StartState *start = new StartState(rootState); - QAbstractTransition *initialTransition = new InitialTransition(initial); - start->addTransition(initialTransition); - QList transitions; - transitions.append(initialTransition); - QEvent nullEvent(QEvent::None); - executeTransitionContent(&nullEvent, transitions); - enterStates(&nullEvent, transitions); - applyProperties(transitions, QList() << start, - QList() << initial); - delete start; - -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": initial configuration:" << configuration; -#endif - _q_process(); -} - -void QStateMachinePrivate::_q_process() -{ - Q_Q(QStateMachine); - Q_ASSERT(state == Running); - Q_ASSERT(!processing); - processing = true; - processingScheduled = false; -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": starting the event processing loop"; -#endif - while (processing) { - if (stop) { - stop = false; - processing = false; - stopProcessingReason = Stopped; - break; - } - QSet enabledTransitions; - QEvent *e = new QEvent(QEvent::None); - enabledTransitions = selectTransitions(e); - if (enabledTransitions.isEmpty()) { - delete e; - e = 0; - } - if (enabledTransitions.isEmpty() && !internalEventQueue.isEmpty()) { - e = internalEventQueue.takeFirst(); -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": dequeued internal event" << e << "of type" << e->type(); -#endif - enabledTransitions = selectTransitions(e); - if (enabledTransitions.isEmpty()) { - delete e; - e = 0; - } - } - if (enabledTransitions.isEmpty()) { - if (externalEventQueue.isEmpty()) { - if (internalEventQueue.isEmpty()) { - processing = false; - stopProcessingReason = EventQueueEmpty; - } - } else { - e = externalEventQueue.takeFirst(); -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": dequeued external event" << e << "of type" << e->type(); -#endif - enabledTransitions = selectTransitions(e); - if (enabledTransitions.isEmpty()) { - delete e; - e = 0; - } - } - } - if (!enabledTransitions.isEmpty()) { - q->beginMicrostep(e); - microstep(e, enabledTransitions.toList()); - q->endMicrostep(e); - } -#ifdef QSTATEMACHINE_DEBUG - else { - qDebug() << q << ": no transitions enabled"; - } -#endif - delete e; - } -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": finished the event processing loop"; -#endif - switch (stopProcessingReason) { - case EventQueueEmpty: - break; - case Finished: - state = NotRunning; - unregisterAllTransitions(); - emit q->finished(); - break; - case Stopped: - state = NotRunning; - unregisterAllTransitions(); - emit q->stopped(); - break; - } -} - -void QStateMachinePrivate::scheduleProcess() -{ - if ((state != Running) || processing || processingScheduled) - return; - processingScheduled = true; - QMetaObject::invokeMethod(q_func(), "_q_process", Qt::QueuedConnection); -} - -void QStateMachinePrivate::registerTransitions(QAbstractState *state) -{ - QState *group = qobject_cast(state); - if (!group) - return; - QList transitions = QStatePrivate::get(group)->transitions(); - for (int i = 0; i < transitions.size(); ++i) { - QAbstractTransition *t = transitions.at(i); - if (QSignalTransition *st = qobject_cast(t)) { - registerSignalTransition(st); - } -#ifndef QT_NO_STATEMACHINE_EVENTFILTER - else if (QEventTransition *oet = qobject_cast(t)) { - registerEventTransition(oet); - } -#endif - } -} - -void QStateMachinePrivate::unregisterTransition(QAbstractTransition *transition) -{ - if (QSignalTransition *st = qobject_cast(transition)) { - unregisterSignalTransition(st); - } -#ifndef QT_NO_STATEMACHINE_EVENTFILTER - else if (QEventTransition *oet = qobject_cast(transition)) { - unregisterEventTransition(oet); - } -#endif -} - -static int senderSignalIndex(const QObject *sender) -{ - QObjectPrivate *d = QObjectPrivate::get(const_cast(sender)); - QMutexLocker(&d->threadData->mutex); - if (!d->currentSender) - return -1; - - // Return -1 if d->currentSender isn't in d->senders - bool found = false; - for (int i = 0; !found && i < d->senders.count(); ++i) - found = (d->senders.at(i)->sender == d->currentSender->sender); - if (!found) - return -1; - return d->currentSender->signal; -} - -void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transition) -{ - Q_Q(QStateMachine); - if (QSignalTransitionPrivate::get(transition)->signalIndex != -1) - return; // already registered - QObject *sender = QSignalTransitionPrivate::get(transition)->sender; - if (!sender) - return; - QByteArray signal = QSignalTransitionPrivate::get(transition)->signal; - if (signal.startsWith('0'+QSIGNAL_CODE)) - signal.remove(0, 1); - int signalIndex = sender->metaObject()->indexOfSignal(signal); - if (signalIndex == -1) { - qWarning("QSignalTransition: no such signal: %s::%s", - sender->metaObject()->className(), signal.constData()); - return; - } - QVector &connectedSignalIndexes = connections[sender]; - if (connectedSignalIndexes.size() <= signalIndex) - connectedSignalIndexes.resize(signalIndex+1); - if (connectedSignalIndexes.at(signalIndex) == 0) { - if (!signalEventGenerator) - signalEventGenerator = new QSignalEventGenerator(q); - bool ok = QMetaObject::connect(sender, signalIndex, signalEventGenerator, - signalEventGenerator->metaObject()->methodOffset()); - if (!ok) { -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": FAILED to add signal transition from" << transition->sourceState() - << ": ( sender =" << sender << ", signal =" << (signal.mid(1)) - << ", targets =" << transition->targetStates() << ")"; -#endif - return; - } - } - ++connectedSignalIndexes[signalIndex]; - QSignalTransitionPrivate::get(transition)->signalIndex = signalIndex; -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": added signal transition from" << transition->sourceState() - << ": ( sender =" << sender << ", signal =" << (signal.mid(1)) - << ", targets =" << transition->targetStates() << ")"; -#endif -} - -void QStateMachinePrivate::unregisterSignalTransition(QSignalTransition *transition) -{ - int signalIndex = QSignalTransitionPrivate::get(transition)->signalIndex; - if (signalIndex == -1) - return; // not registered - QSignalTransitionPrivate::get(transition)->signalIndex = -1; - const QObject *sender = QSignalTransitionPrivate::get(transition)->sender; - QVector &connectedSignalIndexes = connections[sender]; - Q_ASSERT(connectedSignalIndexes.size() > signalIndex); - Q_ASSERT(connectedSignalIndexes.at(signalIndex) != 0); - if (--connectedSignalIndexes[signalIndex] == 0) { - Q_ASSERT(signalEventGenerator != 0); - QMetaObject::disconnect(sender, signalIndex, signalEventGenerator, - signalEventGenerator->metaObject()->methodOffset()); - int sum = 0; - for (int i = 0; i < connectedSignalIndexes.size(); ++i) - sum += connectedSignalIndexes.at(i); - if (sum == 0) - connections.remove(sender); - } -} - -void QStateMachinePrivate::unregisterAllTransitions() -{ - { - QList transitions = qFindChildren(rootState); - for (int i = 0; i < transitions.size(); ++i) - unregisterSignalTransition(transitions.at(i)); - } - { - QList transitions = qFindChildren(rootState); - for (int i = 0; i < transitions.size(); ++i) - unregisterEventTransition(transitions.at(i)); - } -} - -#ifndef QT_NO_STATEMACHINE_EVENTFILTER -void QStateMachinePrivate::registerEventTransition(QEventTransition *transition) -{ - Q_Q(QStateMachine); - if (QEventTransitionPrivate::get(transition)->registered) - return; - if (transition->eventType() >= QEvent::User) { - qWarning("QObject event transitions are not supported for custom types"); - return; - } - QObject *object = QEventTransitionPrivate::get(transition)->object; - if (!object) - return; - QObjectPrivate *od = QObjectPrivate::get(object); - if (!od->eventFilters.contains(q)) - object->installEventFilter(q); - ++qobjectEvents[object][transition->eventType()]; - QEventTransitionPrivate::get(transition)->registered = true; -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": added event transition from" << transition->sourceState() - << ": ( object =" << object << ", event =" << transition->eventType() - << ", targets =" << transition->targetStates() << ")"; -#endif -} - -void QStateMachinePrivate::unregisterEventTransition(QEventTransition *transition) -{ - Q_Q(QStateMachine); - if (!QEventTransitionPrivate::get(transition)->registered) - return; - QObject *object = QEventTransitionPrivate::get(transition)->object; - QHash &events = qobjectEvents[object]; - Q_ASSERT(events.value(transition->eventType()) > 0); - if (--events[transition->eventType()] == 0) { - events.remove(transition->eventType()); - int sum = 0; - QHash::const_iterator it; - for (it = events.constBegin(); it != events.constEnd(); ++it) - sum += it.value(); - if (sum == 0) { - qobjectEvents.remove(object); - object->removeEventFilter(q); - } - } - QEventTransitionPrivate::get(transition)->registered = false; -} -#endif - -void QStateMachinePrivate::handleTransitionSignal(const QObject *sender, int signalIndex, - void **argv) -{ - const QVector &connectedSignalIndexes = connections[sender]; - Q_ASSERT(connectedSignalIndexes.at(signalIndex) != 0); - const QMetaObject *meta = sender->metaObject(); - QMetaMethod method = meta->method(signalIndex); - QList parameterTypes = method.parameterTypes(); - int argc = parameterTypes.count(); - QList vargs; - for (int i = 0; i < argc; ++i) { - int type = QMetaType::type(parameterTypes.at(i)); - vargs.append(QVariant(type, argv[i+1])); - } - -#ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": sending signal event ( sender =" << sender - << ", signal =" << sender->metaObject()->method(signalIndex).signature() << ")"; -#endif - internalEventQueue.append(new QSignalEvent(sender, signalIndex, vargs)); - scheduleProcess(); -} - -/*! - Constructs a new state machine with the given \a parent. -*/ -QStateMachine::QStateMachine(QObject *parent) - : QObject(*new QStateMachinePrivate, parent) -{ -} - -/*! - \internal -*/ -QStateMachine::QStateMachine(QStateMachinePrivate &dd, QObject *parent) - : QObject(dd, parent) -{ -} - -/*! - Destroys this state machine. -*/ -QStateMachine::~QStateMachine() -{ -} - -namespace { - -class RootErrorState : public QAbstractState -{ -public: - RootErrorState(QState *parent) - : QAbstractState(parent) - { - setObjectName(QString::fromLatin1("DefaultErrorState")); - } - - void onEntry(QEvent *) - { - QAbstractStatePrivate *d = QAbstractStatePrivate::get(this); - QStateMachine *machine = d->machine(); - - qWarning("Unrecoverable error detected in running state machine: %s", - qPrintable(machine->errorString())); - } - - void onExit(QEvent *) {} -}; - -class RootState : public QState -{ -public: - RootState(QState *parent) - : QState(parent) - { - } - - void onEntry(QEvent *) {} - void onExit(QEvent *) {} -}; - -} // namespace - -/*! - Returns this state machine's root state. -*/ -QState *QStateMachine::rootState() const -{ - Q_D(const QStateMachine); - if (!d->rootState) { - const_cast(d)->rootState = new RootState(0); - const_cast(d)->initialErrorStateForRoot = new RootErrorState(d->rootState); - d->rootState->setParent(const_cast(this)); - d->rootState->setErrorState(d->initialErrorStateForRoot); - } - return d->rootState; -} - -/*! - Returns the error state of the state machine's root state. - - \sa QState::errorState() -*/ -QAbstractState *QStateMachine::errorState() const -{ - return rootState()->errorState(); -} - -/*! - Sets the error state of this state machine's root state to be \a state. When a running state - machine encounters an error which puts it in an undefined state, it will enter an error state - based on the context of the error that occurred. It will enter this state regardless of what - is currently in the event queue. - - If the erroneous state has an error state set, this will be entered by the machine. If no error - state has been set, the state machine will search the parent hierarchy recursively for an - error state. The error state of the root state can thus be seen as a global error state that - applies for the states for which a more specific error state has not been set. - - Before entering the error state, the state machine will set the error code returned by error() and - error message returned by errorString(). - - The default error state will print a warning to the console containing the information returned by - errorString(). By setting a new error state on either the state machine itself, or on specific - states, you can fine tune error handling in the state machine. - - If the root state's error state is set to 0, or if the error state selected by the machine itself - contains an error, the default error state will be used. - - \sa QState::setErrorState(), rootState() -*/ -void QStateMachine::setErrorState(QAbstractState *state) -{ - rootState()->setErrorState(state); -} - -/*! \enum QStateMachine::Error - - This enum type defines errors that can occur in the state machine at run time. When the state - machine encounters an unrecoverable error at run time, it will set the error code returned - by error(), the error message returned by errorString(), and enter an error state based on - the context of the error. - - \value NoError No error has occurred. - \value NoInitialStateError The machine has entered a QState with children which does not have an - initial state set. The context of this error is the state which is missing an initial - state. - \value NoDefaultStateInHistoryStateError The machine has entered a QHistoryState which does not have - a default state set. The context of this error is the QHistoryState which is missing a - default state. - \value NoCommonAncestorForTransitionError The machine has selected a transition whose source - and targets are not part of the same tree of states, and thus are not part of the same - state machine. Commonly, this could mean that one of the states has not been given - any parent or added to any machine. The context of this error is the source state of - the transition. - - \sa setErrorState() -*/ - -/*! - \enum QStateMachine::RestorePolicy - - This enum specifies the restore policy type. The restore policy - takes effect when the machine enters a state which sets one or more - properties. If the restore policy is set to RestoreProperties, - the state machine will save the original value of the property before the - new value is set. - - Later, when the machine either enters a state which does not set - a value for the given property, the property will automatically be restored - to its initial value. - - Only one initial value will be saved for any given property. If a value for a property has - already been saved by the state machine, it will not be overwritten until the property has been - successfully restored. - - \value DoNotRestoreProperties The state machine should not save the initial values of properties - and restore them later. - \value RestoreProperties The state machine should save the initial values of properties - and restore them later. - - \sa QStateMachine::globalRestorePolicy QState::assignProperty() -*/ - - -/*! - Returns the error code of the last error that occurred in the state machine. -*/ -QStateMachine::Error QStateMachine::error() const -{ - Q_D(const QStateMachine); - return d->error; -} - -/*! - Returns the error string of the last error that occurred in the state machine. -*/ -QString QStateMachine::errorString() const -{ - Q_D(const QStateMachine); - return d->errorString; -} - -/*! - Clears the error string and error code of the state machine. -*/ -void QStateMachine::clearError() -{ - Q_D(QStateMachine); - d->errorString.clear(); - d->error = NoError; -} - -/*! - Returns the restore policy of the state machine. - - \sa setGlobalRestorePolicy() -*/ -QStateMachine::RestorePolicy QStateMachine::globalRestorePolicy() const -{ - Q_D(const QStateMachine); - return d->globalRestorePolicy; -} - -/*! - Sets the restore policy of the state machine to \a restorePolicy. The default - restore policy is QAbstractState::DoNotRestoreProperties. - - \sa globalRestorePolicy() -*/ -void QStateMachine::setGlobalRestorePolicy(QStateMachine::RestorePolicy restorePolicy) -{ - Q_D(QStateMachine); - d->globalRestorePolicy = restorePolicy; -} - -/*! - Returns this state machine's initial state, or 0 if no initial state has - been set. -*/ -QAbstractState *QStateMachine::initialState() const -{ - Q_D(const QStateMachine); - if (!d->rootState) - return 0; - return d->rootState->initialState(); -} - -/*! - Sets this state machine's initial \a state. -*/ -void QStateMachine::setInitialState(QAbstractState *state) -{ - Q_D(QStateMachine); - if (!d->rootState) { - if (!state) - return; - rootState()->setInitialState(state); - } - d->rootState->setInitialState(state); -} - -/*! - Adds the given \a state to this state machine. The state becomes a top-level - state (i.e. a child of the rootState()). - - If the state is already in a different machine, it will first be removed - from its old machine, and then added to this machine. - - \sa removeState(), rootState(), setInitialState() -*/ -void QStateMachine::addState(QAbstractState *state) -{ - if (!state) { - qWarning("QStateMachine::addState: cannot add null state"); - return; - } - if (QAbstractStatePrivate::get(state)->machine() == this) { - qWarning("QStateMachine::addState: state has already been added to this machine"); - return; - } - state->setParent(rootState()); -} - -/*! - Removes the given \a state from this state machine. The state machine - releases ownership of the state. - - \sa addState() -*/ -void QStateMachine::removeState(QAbstractState *state) -{ - if (!state) { - qWarning("QStateMachine::removeState: cannot remove null state"); - return; - } - if (QAbstractStatePrivate::get(state)->machine() != this) { - qWarning("QStateMachine::removeState: state %p's machine (%p)" - " is different from this machine (%p)", - state, QAbstractStatePrivate::get(state)->machine(), this); - return; - } - state->setParent(0); -} - -/*! - Returns whether this state machine is running. - - start(), stop() -*/ -bool QStateMachine::isRunning() const -{ - Q_D(const QStateMachine); - return (d->state == QStateMachinePrivate::Running); -} - -/*! - Starts this state machine. The machine will reset its configuration and - transition to the initial state. When a final top-level state (QFinalState) - is entered, the machine will emit the finished() signal. - - \sa started(), finished(), stop(), initialState() -*/ -void QStateMachine::start() -{ - Q_D(QStateMachine); - - if (rootState()->initialState() == 0) { - qWarning("QStateMachine::start: No initial state set for machine. Refusing to start."); - return; - } - - switch (d->state) { - case QStateMachinePrivate::NotRunning: - d->state = QStateMachinePrivate::Starting; - QMetaObject::invokeMethod(this, "_q_start", Qt::QueuedConnection); - break; - case QStateMachinePrivate::Starting: - break; - case QStateMachinePrivate::Running: - qWarning("QStateMachine::start(): already running"); - break; - } -} - -/*! - Stops this state machine. The state machine will stop processing events and - then emit the stopped() signal. - - \sa stopped(), start() -*/ -void QStateMachine::stop() -{ - Q_D(QStateMachine); - switch (d->state) { - case QStateMachinePrivate::NotRunning: - break; - case QStateMachinePrivate::Starting: - // the machine will exit as soon as it enters the event processing loop - d->stop = true; - break; - case QStateMachinePrivate::Running: - d->stop = true; - d->scheduleProcess(); - break; - } -} - -/*! - Posts the given \a event for processing by this state machine, with a delay - of \a delay milliseconds. - - This function returns immediately. The event is added to the state machine's - event queue. Events are processed in the order posted. The state machine - takes ownership of the event and deletes it once it has been processed. - - You can only post events when the state machine is running. -*/ -void QStateMachine::postEvent(QEvent *event, int delay) -{ - Q_D(QStateMachine); - if (d->state != QStateMachinePrivate::Running) { - qWarning("QStateMachine::postEvent: cannot post event when the state machine is not running"); - return; - } -#ifdef QSTATEMACHINE_DEBUG - qDebug() << this << ": posting external event" << event << "with delay" << delay; -#endif - if (delay) { - int tid = startTimer(delay); - d->delayedEvents[tid] = event; - } else { - d->externalEventQueue.append(event); - d->scheduleProcess(); - } -} - -/*! - \internal - - Posts the given internal \a event for processing by this state machine. -*/ -void QStateMachine::postInternalEvent(QEvent *event) -{ - Q_D(QStateMachine); -#ifdef QSTATEMACHINE_DEBUG - qDebug() << this << ": posting internal event" << event; -#endif - d->internalEventQueue.append(event); - d->scheduleProcess(); -} - -/*! - \internal - - Returns the maximal consistent set of states (including parallel and final - states) that this state machine is currently in. If a state \c s is in the - configuration, it is always the case that the parent of \c s is also in - c. Note, however, that the rootState() is not an explicit member of the - configuration. -*/ -QSet QStateMachine::configuration() const -{ - Q_D(const QStateMachine); - return d->configuration; -} - -/*! - \fn QStateMachine::started() - - This signal is emitted when the state machine has entered its initial state - (QStateMachine::initialState). - - \sa QStateMachine::finished(), QStateMachine::start() -*/ - -/*! - \fn QStateMachine::finished() - - This signal is emitted when the state machine has reached a top-level final - state (QFinalState). - - \sa QStateMachine::started() -*/ - -/*! - \fn QStateMachine::stopped() - - This signal is emitted when the state machine has stopped. - - \sa QStateMachine::stop(), QStateMachine::finished() -*/ - -/*! - \reimp -*/ -bool QStateMachine::event(QEvent *e) -{ - Q_D(QStateMachine); - if (e->type() == QEvent::Timer) { - QTimerEvent *te = static_cast(e); - int tid = te->timerId(); - if (d->delayedEvents.contains(tid)) { - killTimer(tid); - QEvent *ee = d->delayedEvents.take(tid); - d->externalEventQueue.append(ee); - d->scheduleProcess(); - return true; - } - } else if (e->type() == QEvent::ChildAdded) { - QChildEvent *ce = static_cast(e); - if (QAbstractState *state = qobject_cast(ce->child())) { - if (state != rootState()) { - state->setParent(rootState()); - return true; - } - } - } - return QObject::event(e); -} - -#ifndef QT_NO_STATEMACHINE_EVENTFILTER -/*! - \reimp -*/ -bool QStateMachine::eventFilter(QObject *watched, QEvent *event) -{ - Q_D(QStateMachine); - Q_ASSERT(d->qobjectEvents.contains(watched)); - if (d->qobjectEvents[watched].contains(event->type())) - postEvent(new QWrappedEvent(watched, d->handler->cloneEvent(event))); - return false; -} -#endif - -/*! - \internal - - This function is called when the state machine is about to select - transitions based on the given \a event. - - The default implementation does nothing. -*/ -void QStateMachine::beginSelectTransitions(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \internal - - This function is called when the state machine has finished selecting - transitions based on the given \a event. - - The default implementation does nothing. -*/ -void QStateMachine::endSelectTransitions(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \internal - - This function is called when the state machine is about to do a microstep. - - The default implementation does nothing. -*/ -void QStateMachine::beginMicrostep(QEvent *event) -{ - Q_UNUSED(event); -} - -/*! - \internal - - This function is called when the state machine has finished doing a - microstep. - - The default implementation does nothing. -*/ -void QStateMachine::endMicrostep(QEvent *event) -{ - Q_UNUSED(event); -} - -#ifndef QT_NO_ANIMATION - -/*! - Returns whether animations are enabled for this state machine. -*/ -bool QStateMachine::animationsEnabled() const -{ - Q_D(const QStateMachine); - return d->animationsEnabled; -} - -/*! - Sets whether animations are \a enabled for this state machine. -*/ -void QStateMachine::setAnimationsEnabled(bool enabled) -{ - Q_D(QStateMachine); - d->animationsEnabled = enabled; -} - -/*! - Adds a default \a animation to be considered for any transition. -*/ -void QStateMachine::addDefaultAnimation(QAbstractAnimation *animation) -{ - Q_D(QStateMachine); - d->defaultAnimations.append(animation); -} - -/*! - Returns the list of default animations that will be considered for any transition. -*/ -QList QStateMachine::defaultAnimations() const -{ - Q_D(const QStateMachine); - return d->defaultAnimations; -} - -/*! - Removes \a animation from the list of default animations. -*/ -void QStateMachine::removeDefaultAnimation(QAbstractAnimation *animation) -{ - Q_D(QStateMachine); - d->defaultAnimations.removeAll(animation); -} - -#endif // QT_NO_ANIMATION - - -static const uint qt_meta_data_QSignalEventGenerator[] = { - - // content: - 2, // revision - 0, // classname - 0, 0, // classinfo - 1, 12, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - - // slots: signature, parameters, type, tag, flags - 23, 22, 22, 22, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_QSignalEventGenerator[] = { - "QSignalEventGenerator\0\0execute()\0" -}; - -const QMetaObject QSignalEventGenerator::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_QSignalEventGenerator, - qt_meta_data_QSignalEventGenerator, 0 } -}; - -const QMetaObject *QSignalEventGenerator::metaObject() const -{ - return &staticMetaObject; -} - -void *QSignalEventGenerator::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_QSignalEventGenerator)) - return static_cast(const_cast< QSignalEventGenerator*>(this)); - return QObject::qt_metacast(_clname); -} - -int QSignalEventGenerator::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - switch (_id) { - case 0: { -// ### in Qt 4.6 we can use QObject::senderSignalIndex() - int signalIndex = senderSignalIndex(this); - Q_ASSERT(signalIndex != -1); - QStateMachine *machine = qobject_cast(parent()); - QStateMachinePrivate::get(machine)->handleTransitionSignal(sender(), signalIndex, _a); - break; - } - default: ; - } - _id -= 1; - } - return _id; -} - -QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent) - : QObject(parent) -{ -} - -/*! - \class QSignalEvent - - \brief The QSignalEvent class represents a Qt signal event. - - \since 4.6 - \ingroup statemachine - - A signal event is generated by a QStateMachine in response to a Qt - signal. The QSignalTransition class provides a transition associated with a - signal event. QSignalEvent is part of \l{The State Machine Framework}. - - The sender() function returns the object that generated the signal. The - signalIndex() function returns the index of the signal. The arguments() - function returns the arguments of the signal. - - \sa QSignalTransition -*/ - -/*! - \internal - - Constructs a new QSignalEvent object with the given \a sender, \a - signalIndex and \a arguments. -*/ -QSignalEvent::QSignalEvent(const QObject *sender, int signalIndex, - const QList &arguments) - : QEvent(QEvent::Signal), m_sender(sender), - m_signalIndex(signalIndex), m_arguments(arguments) -{ -} - -/*! - Destroys this QSignalEvent. -*/ -QSignalEvent::~QSignalEvent() -{ -} - -/*! - \fn QSignalEvent::sender() const - - Returns the object that emitted the signal. - - \sa QObject::sender() -*/ - -/*! - \fn QSignalEvent::signalIndex() const - - Returns the index of the signal. - - \sa QMetaObject::indexOfSignal(), QMetaObject::method() -*/ - -/*! - \fn QSignalEvent::arguments() const - - Returns the arguments of the signal. -*/ - - -/*! - \class QWrappedEvent - - \brief The QWrappedEvent class holds a clone of an event associated with a QObject. - - \since 4.6 - \ingroup statemachine - - A wrapped event is generated by a QStateMachine in response to a Qt - event. The QEventTransition class provides a transition associated with a - such an event. QWrappedEvent is part of \l{The State Machine Framework}. - - The object() function returns the object that generated the event. The - event() function returns a clone of the original event. - - \sa QEventTransition -*/ - -/*! - \internal - - Constructs a new QWrappedEvent object with the given \a object - and \a event. -*/ -QWrappedEvent::QWrappedEvent(QObject *object, QEvent *event) - : QEvent(QEvent::Wrapped), m_object(object), m_event(event) -{ -} - -/*! - Destroys this QWrappedEvent. -*/ -QWrappedEvent::~QWrappedEvent() -{ -} - -/*! - \fn QWrappedEvent::object() const - - Returns the object that the event is associated with. -*/ - -/*! - \fn QWrappedEvent::event() const - - Returns a clone of the original event. -*/ - -QT_END_NAMESPACE - -#include "moc_qstatemachine.cpp" diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h deleted file mode 100644 index 2a98a9a..0000000 --- a/src/corelib/statemachine/qstatemachine.h +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSTATEMACHINE_H -#define QSTATEMACHINE_H - -#include - -#include -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QEvent; -class QAbstractState; -class QState; - -class QStateMachinePrivate; -class QAbstractAnimation; -class QAbstractState; -class Q_CORE_EXPORT QStateMachine : public QObject -{ - Q_OBJECT - Q_PROPERTY(QState* rootState READ rootState) - Q_PROPERTY(QAbstractState* initialState READ initialState WRITE setInitialState) - Q_PROPERTY(QAbstractState* errorState READ errorState WRITE setErrorState) - Q_PROPERTY(QString errorString READ errorString) - Q_PROPERTY(RestorePolicy globalRestorePolicy READ globalRestorePolicy WRITE setGlobalRestorePolicy) - Q_ENUMS(RestorePolicy) -#ifndef QT_NO_ANIMATION - Q_PROPERTY(bool animationsEnabled READ animationsEnabled WRITE setAnimationsEnabled) -#endif -public: - enum RestorePolicy { - DoNotRestoreProperties, - RestoreProperties - }; - - enum Error { - NoError, - NoInitialStateError, - NoDefaultStateInHistoryStateError, - NoCommonAncestorForTransitionError - }; - - QStateMachine(QObject *parent = 0); - ~QStateMachine(); - - void addState(QAbstractState *state); - void removeState(QAbstractState *state); - - QState *rootState() const; - - QAbstractState *initialState() const; - void setInitialState(QAbstractState *state); - - QAbstractState *errorState() const; - void setErrorState(QAbstractState *state); - - Error error() const; - QString errorString() const; - void clearError(); - - bool isRunning() const; - -#ifndef QT_NO_ANIMATION - bool animationsEnabled() const; - void setAnimationsEnabled(bool enabled); - - void addDefaultAnimation(QAbstractAnimation *animation); - QList defaultAnimations() const; - void removeDefaultAnimation(QAbstractAnimation *animation); -#endif // QT_NO_ANIMATION - - QStateMachine::RestorePolicy globalRestorePolicy() const; - void setGlobalRestorePolicy(QStateMachine::RestorePolicy restorePolicy); - - void postEvent(QEvent *event, int delay = 0); - - QSet configuration() const; - -#ifndef QT_NO_STATEMACHINE_EVENTFILTER - bool eventFilter(QObject *watched, QEvent *event); -#endif - -public Q_SLOTS: - void start(); - void stop(); - -Q_SIGNALS: - void started(); - void stopped(); - void finished(); - -protected: - void postInternalEvent(QEvent *event); - - virtual void beginSelectTransitions(QEvent *event); - virtual void endSelectTransitions(QEvent *event); - - virtual void beginMicrostep(QEvent *event); - virtual void endMicrostep(QEvent *event); - - bool event(QEvent *e); - -protected: - QStateMachine(QStateMachinePrivate &dd, QObject *parent); - -private: - Q_DISABLE_COPY(QStateMachine) - Q_DECLARE_PRIVATE(QStateMachine) - Q_PRIVATE_SLOT(d_func(), void _q_start()) - Q_PRIVATE_SLOT(d_func(), void _q_process()) -#ifndef QT_NO_ANIMATION - Q_PRIVATE_SLOT(d_func(), void _q_animationFinished()) -#endif -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h deleted file mode 100644 index dfa5575..0000000 --- a/src/corelib/statemachine/qstatemachine_p.h +++ /dev/null @@ -1,217 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSTATEMACHINE_P_H -#define QSTATEMACHINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include -#include -#include - -#include "qstate.h" -#include "qstate_p.h" - -QT_BEGIN_NAMESPACE - -class QEvent; -#ifndef QT_NO_STATEMACHINE_EVENTFILTER -class QEventTransition; -#endif -class QSignalEventGenerator; -class QSignalTransition; -class QAbstractState; -class QAbstractTransition; -class QState; - -#ifndef QT_NO_ANIMATION -class QAbstractAnimation; -#endif - -class QStateMachine; -class Q_CORE_EXPORT QStateMachinePrivate - : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QStateMachine) -public: - enum State { - NotRunning, - Starting, - Running - }; - enum StopProcessingReason { - EventQueueEmpty, - Finished, - Stopped - }; - - QStateMachinePrivate(); - ~QStateMachinePrivate(); - - static QStateMachinePrivate *get(QStateMachine *q); - - static QState *findLCA(const QList &states); - - static bool stateEntryLessThan(QAbstractState *s1, QAbstractState *s2); - static bool stateExitLessThan(QAbstractState *s1, QAbstractState *s2); - - QAbstractState *findErrorState(QAbstractState *context); - void setError(QStateMachine::Error error, QAbstractState *currentContext); - - // private slots - void _q_start(); - void _q_process(); -#ifndef QT_NO_ANIMATION - void _q_animationFinished(); -#endif - - void microstep(QEvent *event, const QList &transitionList); - bool isPreempted(const QAbstractState *s, const QSet &transitions) const; - QSet selectTransitions(QEvent *event) const; - QList exitStates(QEvent *event, const QList &transitionList); - void executeTransitionContent(QEvent *event, const QList &transitionList); - QList enterStates(QEvent *event, const QList &enabledTransitions); - void addStatesToEnter(QAbstractState *s, QState *root, - QSet &statesToEnter, - QSet &statesForDefaultEntry); - - void applyProperties(const QList &transitionList, - const QList &exitedStates, - const QList &enteredStates); - - bool isInFinalState(QAbstractState *s) const; - static bool isFinal(const QAbstractState *s); - static bool isParallel(const QAbstractState *s); - static bool isCompound(const QAbstractState *s); - static bool isAtomic(const QAbstractState *s); - static bool isDescendantOf(const QAbstractState *s, const QAbstractState *other); - static QList properAncestors(const QAbstractState *s, const QState *upperBound); - - void registerTransitions(QAbstractState *state); - void registerSignalTransition(QSignalTransition *transition); - void unregisterSignalTransition(QSignalTransition *transition); -#ifndef QT_NO_STATEMACHINE_EVENTFILTER - void registerEventTransition(QEventTransition *transition); - void unregisterEventTransition(QEventTransition *transition); -#endif - void unregisterTransition(QAbstractTransition *transition); - void unregisterAllTransitions(); - void handleTransitionSignal(const QObject *sender, int signalIndex, - void **args); - void scheduleProcess(); - - typedef QPair RestorableId; - QHash registeredRestorables; - void registerRestorable(QObject *object, const QByteArray &propertyName); - void unregisterRestorable(QObject *object, const QByteArray &propertyName); - bool hasRestorable(QObject *object, const QByteArray &propertyName) const; - QVariant restorableValue(QObject *object, const QByteArray &propertyName) const; - QList restorablesToPropertyList(const QHash &restorables) const; - - State state; - bool processing; - bool processingScheduled; - bool stop; - StopProcessingReason stopProcessingReason; - QState *rootState; - QSet configuration; - QList internalEventQueue; - QList externalEventQueue; - - QStateMachine::Error error; - QStateMachine::RestorePolicy globalRestorePolicy; - - QString errorString; - QSet pendingErrorStates; - QSet pendingErrorStatesForDefaultEntry; - QAbstractState *initialErrorStateForRoot; - -#ifndef QT_NO_ANIMATION - bool animationsEnabled; - - QPair, QList > - initializeAnimation(QAbstractAnimation *abstractAnimation, - const QPropertyAssignment &prop); - - QHash > animationsForState; - QHash propertyForAnimation; - QHash stateForAnimation; - QSet resetAnimationEndValues; - - QList defaultAnimations; - QMultiHash defaultAnimationsForSource; - QMultiHash defaultAnimationsForTarget; - -#endif // QT_NO_ANIMATION - - QSignalEventGenerator *signalEventGenerator; - - QHash > connections; -#ifndef QT_NO_STATEMACHINE_EVENTFILTER - QHash > qobjectEvents; -#endif - QHash delayedEvents; - - typedef QEvent* (*f_cloneEvent)(QEvent*); - struct Handler { - f_cloneEvent cloneEvent; - }; - - static const Handler *handler; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/corelib/statemachine/qwrappedevent.h b/src/corelib/statemachine/qwrappedevent.h deleted file mode 100644 index b01c608..0000000 --- a/src/corelib/statemachine/qwrappedevent.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWRAPPEDEVENT_H -#define QWRAPPEDEVENT_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QObject; - -class Q_CORE_EXPORT QWrappedEvent : public QEvent -{ -public: - QWrappedEvent(QObject *object, QEvent *event); - ~QWrappedEvent(); - - inline QObject *object() const { return m_object; } - inline QEvent *event() const { return m_event; } - -private: - QObject *m_object; - QEvent *m_event; - -private: - Q_DISABLE_COPY(QWrappedEvent) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/statemachine/statemachine.pri b/src/corelib/statemachine/statemachine.pri deleted file mode 100644 index 5b19bc1..0000000 --- a/src/corelib/statemachine/statemachine.pri +++ /dev/null @@ -1,30 +0,0 @@ -HEADERS += $$PWD/qstatemachine.h \ - $$PWD/qstatemachine_p.h \ - $$PWD/qsignaleventgenerator_p.h \ - $$PWD/qabstractstate.h \ - $$PWD/qabstractstate_p.h \ - $$PWD/qstate.h \ - $$PWD/qstate_p.h \ - $$PWD/qfinalstate.h \ - $$PWD/qhistorystate.h \ - $$PWD/qhistorystate_p.h \ - $$PWD/qabstracttransition.h \ - $$PWD/qabstracttransition_p.h \ - $$PWD/qsignalevent.h \ - $$PWD/qsignaltransition.h \ - $$PWD/qsignaltransition_p.h - -SOURCES += $$PWD/qstatemachine.cpp \ - $$PWD/qabstractstate.cpp \ - $$PWD/qstate.cpp \ - $$PWD/qfinalstate.cpp \ - $$PWD/qhistorystate.cpp \ - $$PWD/qabstracttransition.cpp \ - $$PWD/qsignaltransition.cpp - -!contains(DEFINES, QT_NO_STATEMACHINE_EVENTFILTER) { -HEADERS += $$PWD/qwrappedevent.h \ - $$PWD/qeventtransition.h \ - $$PWD/qeventtransition_p.h -SOURCES += $$PWD/qeventtransition.cpp -} diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp deleted file mode 100644 index 2b027fc..0000000 --- a/src/corelib/tools/qeasingcurve.cpp +++ /dev/null @@ -1,846 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - -| *property* | *Used for type* | -| period | QEasingCurve::{In,Out,InOut,OutIn}Elastic | -| amplitude | QEasingCurve::{In,Out,InOut,OutIn}Bounce, QEasingCurve::{In,Out,InOut,OutIn}Elastic | -| overshoot | QEasingCurve::{In,Out,InOut,OutIn}Back | - -*/ - - - - -/*! - \class QEasingCurve - \since 4.6 - \ingroup animation - \brief The QEasingCurve class provides easing curves for controlling animation. - - Easing curves describe a function that controls how the speed of the interpolation - between 0 and 1 should be. Easing curves allow transitions from - one value to another to appear more natural than a simple constant speed would allow. - The QEasingCurve class is usually used in conjunction with the QAnimation class, - but can be used on its own. - - To calculate the speed of the interpolation, the easing curve provides the function - valueForProgress(), where the \a progress argument specifies the progress of the - interpolation: 0 is the start value of the interpolation, 1 is the end value of the - interpolation. The returned value is the effective progress of the interpolation. - If the returned value is the same as the input value for all input values the easing - curve is a linear curve. This is the default behaviour. - - For example, - \code - QEasingCurve easing(QEasingCurve::InOutQuad); - - for(qreal t = 0.0; t < 1.0; t+=0.1) - qWarning() << "Effective progress" << t << " is - << easing.valueForProgress(t); - \endcode - will print the effective progress of the interpolation between 0 and 1. - - When using a QAnimation, the easing curve will be used to control the - progress of the interpolation between startValue and endValue: - \code - QAnimation animation; - animation.setStartValue(0); - animation.setEndValue(1000); - animation.setDuration(1000); - animation.setEasingCurve(QEasingCurve::InOutQuad); - \endcode - */ - -/*! - \enum QEasingCurve::Type - - The type of easing curve. - - \value Linear \inlineimage qeasingcurve-linear.png - \br - Easing equation function for a simple linear tweening, - with no easing. - \value InQuad \inlineimage qeasingcurve-inquad.png - \br - Easing equation function for a quadratic (t^2) easing - in: accelerating from zero velocity. - \value OutQuad \inlineimage qeasingcurve-outquad.png - \br - Easing equation function for a quadratic (t^2) easing - out: decelerating to zero velocity. - \value InOutQuad \inlineimage qeasingcurve-inoutquad.png - \br - Easing equation function for a quadratic (t^2) easing - in/out: acceleration until halfway, then deceleration. - \value OutInQuad \inlineimage qeasingcurve-outinquad.png - \br - Easing equation function for a quadratic (t^2) easing - out/in: deceleration until halfway, then acceleration. - \value InCubic \inlineimage qeasingcurve-incubic.png - \br - Easing equation function for a cubic (t^3) easing - in: accelerating from zero velocity. - \value OutCubic \inlineimage qeasingcurve-outcubic.png - \br - Easing equation function for a cubic (t^3) easing - out: decelerating from zero velocity. - \value InOutCubic \inlineimage qeasingcurve-inoutcubic.png - \br - Easing equation function for a cubic (t^3) easing - in/out: acceleration until halfway, then deceleration. - \value OutInCubic \inlineimage qeasingcurve-outincubic.png - \br - Easing equation function for a cubic (t^3) easing - out/in: deceleration until halfway, then acceleration. - \value InQuart \inlineimage qeasingcurve-inquart.png - \br - Easing equation function for a quartic (t^4) easing - in: accelerating from zero velocity. - \value OutQuart \inlineimage qeasingcurve-outquart.png - \br - Easing equation function for a quartic (t^4) easing - out: decelerating from zero velocity. - \value InOutQuart \inlineimage qeasingcurve-inoutquart.png - \br - Easing equation function for a quartic (t^4) easing - in/out: acceleration until halfway, then deceleration. - \value OutInQuart \inlineimage qeasingcurve-outinquart.png - \br - Easing equation function for a quartic (t^4) easing - out/in: deceleration until halfway, then acceleration. - \value InQuint \inlineimage qeasingcurve-inquint.png - \br - Easing equation function for a quintic (t^5) easing - in: accelerating from zero velocity. - \value OutQuint \inlineimage qeasingcurve-outquint.png - \br - Easing equation function for a quintic (t^5) easing - out: decelerating from zero velocity. - \value InOutQuint \inlineimage qeasingcurve-inoutquint.png - \br - Easing equation function for a quintic (t^5) easing - in/out: acceleration until halfway, then deceleration. - \value OutInQuint \inlineimage qeasingcurve-outinquint.png - \br - Easing equation function for a quintic (t^5) easing - out/in: deceleration until halfway, then acceleration. - \value InSine \inlineimage qeasingcurve-insine.png - \br - Easing equation function for a sinusoidal (sin(t)) easing - in: accelerating from zero velocity. - \value OutSine \inlineimage qeasingcurve-outsine.png - \br - Easing equation function for a sinusoidal (sin(t)) easing - out: decelerating from zero velocity. - \value InOutSine \inlineimage qeasingcurve-inoutsine.png - \br - Easing equation function for a sinusoidal (sin(t)) easing - in/out: acceleration until halfway, then deceleration. - \value OutInSine \inlineimage qeasingcurve-outinsine.png - \br - Easing equation function for a sinusoidal (sin(t)) easing - out/in: deceleration until halfway, then acceleration. - \value InExpo \inlineimage qeasingcurve-inexpo.png - \br - Easing equation function for an exponential (2^t) easing - in: accelerating from zero velocity. - \value OutExpo \inlineimage qeasingcurve-outexpo.png - \br - Easing equation function for an exponential (2^t) easing - out: decelerating from zero velocity. - \value InOutExpo \inlineimage qeasingcurve-inoutexpo.png - \br - Easing equation function for an exponential (2^t) easing - in/out: acceleration until halfway, then deceleration. - \value OutInExpo \inlineimage qeasingcurve-outinexpo.png - \br - Easing equation function for an exponential (2^t) easing - out/in: deceleration until halfway, then acceleration. - \value InCirc \inlineimage qeasingcurve-incirc.png - \br - Easing equation function for a circular (sqrt(1-t^2)) easing - in: accelerating from zero velocity. - \value OutCirc \inlineimage qeasingcurve-outcirc.png - \br - Easing equation function for a circular (sqrt(1-t^2)) easing - out: decelerating from zero velocity. - \value InOutCirc \inlineimage qeasingcurve-inoutcirc.png - \br - Easing equation function for a circular (sqrt(1-t^2)) easing - in/out: acceleration until halfway, then deceleration. - \value OutInCirc \inlineimage qeasingcurve-outincirc.png - \br - Easing equation function for a circular (sqrt(1-t^2)) easing - out/in: deceleration until halfway, then acceleration. - \value InElastic \inlineimage qeasingcurve-inelastic.png - \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing in: - accelerating from zero velocity. The peak amplitude - can be set with the \e amplitude parameter, and the - period of decay by the \e period parameter. - \value OutElastic \inlineimage qeasingcurve-outelastic.png - \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing out: - decelerating from zero velocity. The peak amplitude - can be set with the \e amplitude parameter, and the - period of decay by the \e period parameter. - \value InOutElastic \inlineimage qeasingcurve-inoutelastic.png - \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing in/out: - acceleration until halfway, then deceleration. - \value OutInElastic \inlineimage qeasingcurve-outinelastic.png - \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing out/in: - deceleration until halfway, then acceleration. - \value InBack \inlineimage qeasingcurve-inback.png - \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing in: - accelerating from zero velocity. - \value OutBack \inlineimage qeasingcurve-outback.png - \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing out: - decelerating from zero velocity. - \value InOutBack \inlineimage qeasingcurve-inoutback.png - \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing in/out: - acceleration until halfway, then deceleration. - \value OutInBack \inlineimage qeasingcurve-outinback.png - \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing out/in: - deceleration until halfway, then acceleration. - \value InBounce \inlineimage qeasingcurve-inbounce.png - \br - Easing equation function for a bounce (exponentially - decaying parabolic bounce) easing in: accelerating - from zero velocity. - \value OutBounce \inlineimage qeasingcurve-outbounce.png - \br - Easing equation function for a bounce (exponentially - decaying parabolic bounce) easing out: decelerating - from zero velocity. - \value InOutBounce \inlineimage qeasingcurve-inoutbounce.png - \br - Easing equation function for a bounce (exponentially - decaying parabolic bounce) easing in/out: - acceleration until halfway, then deceleration. - \value OutInBounce \inlineimage qeasingcurve-outinbounce.png - \br - Easing equation function for a bounce (exponentially - decaying parabolic bounce) easing out/in: - deceleration until halfway, then acceleration. - \omitvalue InCurve - \omitvalue OutCurve - \omitvalue SineCurve - \omitvalue CosineCurve - \value Custom This is returned if the user have specified a custom curve type with setCustomType(). Note that you cannot call setType() with this value, but type() can return it. - \omitvalue NCurveTypes -*/ - -/*! - \typedef QEasingCurve::EasingFunction - - This is a typedef for a pointer to a function with the following - signature: - - \snippet doc/src/snippets/code/src_corelib_tools_qeasingcurve.cpp 0 -*/ - -#include "qeasingcurve.h" - -#ifndef QT_NO_DEBUG_STREAM -#include -#include -#endif - -QT_BEGIN_NAMESPACE - -static bool isConfigFunction(QEasingCurve::Type type) -{ - return type >= QEasingCurve::InElastic - && type <= QEasingCurve::OutInBounce; -} - -class QEasingCurveFunction -{ -public: - enum Type { In, Out, InOut, OutIn }; - - QEasingCurveFunction(QEasingCurveFunction::Type type = In, qreal period = 0.3, qreal amplitude = 1.0, - qreal overshoot = 1.70158f) - : _t(type), _p(period), _a(amplitude), _o(overshoot) - { } - virtual ~QEasingCurveFunction() {} - virtual qreal value(qreal t); - virtual QEasingCurveFunction *copy() const; - bool operator==(const QEasingCurveFunction& other); - - Type _t; - qreal _p; - qreal _a; - qreal _o; -}; - -qreal QEasingCurveFunction::value(qreal t) -{ - return t; -} - -QEasingCurveFunction *QEasingCurveFunction::copy() const -{ - return new QEasingCurveFunction(_t, _p, _a, _o); -} - -bool QEasingCurveFunction::operator==(const QEasingCurveFunction& other) -{ - return _t == other._t && - _p == other._p && - _a == other._a && - _o == other._o; -} - -QT_BEGIN_INCLUDE_NAMESPACE -#include "../../3rdparty/easing/easing.cpp" -QT_END_INCLUDE_NAMESPACE - -class QEasingCurvePrivate -{ -public: - QEasingCurvePrivate() - : type(QEasingCurve::Linear), - config(0), - func(&easeNone) - { } - ~QEasingCurvePrivate() { delete config; } - void setType_helper(QEasingCurve::Type); - - QEasingCurve::Type type; - QEasingCurveFunction *config; - QEasingCurve::EasingFunction func; -}; - -struct ElasticEase : public QEasingCurveFunction -{ - ElasticEase(Type type) - : QEasingCurveFunction(type, qreal(0.3), qreal(1.0)) - { } - - QEasingCurveFunction *copy() const - { - ElasticEase *rv = new ElasticEase(_t); - rv->_p = _p; - rv->_a = _a; - return rv; - } - - qreal value(qreal t) - { - qreal p = (_p < 0) ? 0.3f : _p; - qreal a = (_a < 0) ? 1.0f : _a; - switch(_t) { - case In: - return easeInElastic(t, a, p); - case Out: - return easeOutElastic(t, a, p); - case InOut: - return easeInOutElastic(t, a, p); - case OutIn: - return easeOutInElastic(t, a, p); - default: - return t; - } - } -}; - -struct BounceEase : public QEasingCurveFunction -{ - BounceEase(Type type) - : QEasingCurveFunction(type, 0.3f, 1.0f) - { } - - QEasingCurveFunction *copy() const - { - BounceEase *rv = new BounceEase(_t); - rv->_a = _a; - return rv; - } - - qreal value(qreal t) - { - qreal a = (_a < 0) ? 1.0f : _a; - switch(_t) { - case In: - return easeInBounce(t, a); - case Out: - return easeOutBounce(t, a); - case InOut: - return easeInOutBounce(t, a); - case OutIn: - return easeOutInBounce(t, a); - default: - return t; - } - } -}; - -struct BackEase : public QEasingCurveFunction -{ - BackEase(Type type) - : QEasingCurveFunction(type, 0.3f, 1.0f, 1.70158f) - { } - - QEasingCurveFunction *copy() const - { - BackEase *rv = new BackEase(_t); - rv->_o = _o; - return rv; - } - - qreal value(qreal t) - { - qreal o = (_o < 0) ? 1.70158f : _o; - switch(_t) { - case In: - return easeInBack(t, o); - case Out: - return easeOutBack(t, o); - case InOut: - return easeInOutBack(t, o); - case OutIn: - return easeOutInBack(t, o); - default: - return t; - } - } -}; - -static QEasingCurve::EasingFunction curveToFunc(QEasingCurve::Type curve) -{ - switch(curve) { - case QEasingCurve::Linear: - return &easeNone; - case QEasingCurve::InQuad: - return &easeInQuad; - case QEasingCurve::OutQuad: - return &easeOutQuad; - case QEasingCurve::InOutQuad: - return &easeInOutQuad; - case QEasingCurve::OutInQuad: - return &easeOutInQuad; - case QEasingCurve::InCubic: - return &easeInCubic; - case QEasingCurve::OutCubic: - return &easeOutCubic; - case QEasingCurve::InOutCubic: - return &easeInOutCubic; - case QEasingCurve::OutInCubic: - return &easeOutInCubic; - case QEasingCurve::InQuart: - return &easeInQuart; - case QEasingCurve::OutQuart: - return &easeOutQuart; - case QEasingCurve::InOutQuart: - return &easeInOutQuart; - case QEasingCurve::OutInQuart: - return &easeOutInQuart; - case QEasingCurve::InQuint: - return &easeInQuint; - case QEasingCurve::OutQuint: - return &easeOutQuint; - case QEasingCurve::InOutQuint: - return &easeInOutQuint; - case QEasingCurve::OutInQuint: - return &easeOutInQuint; - case QEasingCurve::InSine: - return &easeInSine; - case QEasingCurve::OutSine: - return &easeOutSine; - case QEasingCurve::InOutSine: - return &easeInOutSine; - case QEasingCurve::OutInSine: - return &easeOutInSine; - case QEasingCurve::InExpo: - return &easeInExpo; - case QEasingCurve::OutExpo: - return &easeOutExpo; - case QEasingCurve::InOutExpo: - return &easeInOutExpo; - case QEasingCurve::OutInExpo: - return &easeOutInExpo; - case QEasingCurve::InCirc: - return &easeInCirc; - case QEasingCurve::OutCirc: - return &easeOutCirc; - case QEasingCurve::InOutCirc: - return &easeInOutCirc; - case QEasingCurve::OutInCirc: - return &easeOutInCirc; - // Internal for, compatibility with QTimeLine only ?? - case QEasingCurve::InCurve: - return &easeInCurve; - case QEasingCurve::OutCurve: - return &easeOutCurve; - case QEasingCurve::SineCurve: - return &easeSineCurve; - case QEasingCurve::CosineCurve: - return &easeCosineCurve; - default: - return 0; - }; -} - -static QEasingCurveFunction *curveToFunctionObject(QEasingCurve::Type type) -{ - QEasingCurveFunction *curveFunc = 0; - switch(type) { - case QEasingCurve::InElastic: - curveFunc = new ElasticEase(ElasticEase::In); - break; - case QEasingCurve::OutElastic: - curveFunc = new ElasticEase(ElasticEase::Out); - break; - case QEasingCurve::InOutElastic: - curveFunc = new ElasticEase(ElasticEase::InOut); - break; - case QEasingCurve::OutInElastic: - curveFunc = new ElasticEase(ElasticEase::OutIn); - break; - case QEasingCurve::OutBounce: - curveFunc = new BounceEase(BounceEase::Out); - break; - case QEasingCurve::InBounce: - curveFunc = new BounceEase(BounceEase::In); - break; - case QEasingCurve::OutInBounce: - curveFunc = new BounceEase(BounceEase::OutIn); - break; - case QEasingCurve::InOutBounce: - curveFunc = new BounceEase(BounceEase::InOut); - break; - case QEasingCurve::InBack: - curveFunc = new BackEase(BackEase::In); - break; - case QEasingCurve::OutBack: - curveFunc = new BackEase(BackEase::Out); - break; - case QEasingCurve::InOutBack: - curveFunc = new BackEase(BackEase::InOut); - break; - case QEasingCurve::OutInBack: - curveFunc = new BackEase(BackEase::OutIn); - break; - default: - curveFunc = new QEasingCurveFunction(QEasingCurveFunction::In, 0.3f, 1.0f, 1.70158f); // ### - } - - return curveFunc; -} - -/*! - Constructs an easing curve of the given \a type. - */ -QEasingCurve::QEasingCurve(Type type) - : d_ptr(new QEasingCurvePrivate) -{ - setType(type); -} - -/*! - Construct a copy of \a other. - */ -QEasingCurve::QEasingCurve(const QEasingCurve &other) -: d_ptr(new QEasingCurvePrivate) -{ - // ### non-atomic, requires malloc on shallow copy - *d_ptr = *other.d_ptr; - if(other.d_ptr->config) - d_ptr->config = other.d_ptr->config->copy(); -} - -/*! - Destructor. - */ - -QEasingCurve::~QEasingCurve() -{ - delete d_ptr; -} - -/*! - Copy \a other. - */ -QEasingCurve &QEasingCurve::operator=(const QEasingCurve &other) -{ - // ### non-atomic, requires malloc on shallow copy - if (d_ptr->config) { - delete d_ptr->config; - d_ptr->config = 0; - } - - *d_ptr = *other.d_ptr; - if(other.d_ptr->config) - d_ptr->config = other.d_ptr->config->copy(); - - return *this; -} - -/*! - Compare this easing curve with \a other and returns true if they are - equal. It will also compare the properties of a curve. - */ -bool QEasingCurve::operator==(const QEasingCurve &other) const -{ - bool res = d_ptr->func == other.d_ptr->func - && d_ptr->type == other.d_ptr->type; - if (res && d_ptr->config && other.d_ptr->config) { - // catch the config content - res = d_ptr->config->operator==(*(other.d_ptr->config)); - } - return res; -} - -/*! - \fn bool QEasingCurve::operator!=(const QEasingCurve &other) const - Compare this easing curve with \a other and returns true if they are not equal. - It will also compare the properties of a curve. - - \sa operator==() -*/ - -/*! - Returns the amplitude. This is not applicable for all curve types. - It is only applicable for bounce and elastic curves (curves of type() - QEasingCurve::InBounce, QEasingCurve::OutBounce, QEasingCurve::InOutBounce, - QEasingCurve::OutInBounce, QEasingCurve::InElastic, QEasingCurve::OutElastic, - QEasingCurve::InOutElastic or QEasingCurve::OutInElastic). - */ -qreal QEasingCurve::amplitude() const -{ - return d_ptr->config ? d_ptr->config->_a : 1.0; -} - -/*! - Sets the amplitude to \a amplitude. - - This will set the amplitude of the bounce or the amplitude of the - elastic "spring" effect. The higher the number, the higher the amplitude. - \sa amplitude() -*/ -void QEasingCurve::setAmplitude(qreal amplitude) -{ - if (!d_ptr->config) - d_ptr->config = curveToFunctionObject(d_ptr->type); - d_ptr->config->_a = amplitude; -} - -/*! - Returns the period. This is not applicable for all curve types. - It is only applicable if type() is QEasingCurve::InElastic, QEasingCurve::OutElastic, - QEasingCurve::InOutElastic or QEasingCurve::OutInElastic. - */ -qreal QEasingCurve::period() const -{ - return d_ptr->config ? d_ptr->config->_p : 0.3; -} - -/*! - Sets the period to \a period. - Setting a small period value will give a high frequency of the curve. A - large period will give it a small frequency. - - \sa period() -*/ -void QEasingCurve::setPeriod(qreal period) -{ - if (!d_ptr->config) - d_ptr->config = curveToFunctionObject(d_ptr->type); - d_ptr->config->_p = period; -} - -/*! - Returns the overshoot. This is not applicable for all curve types. - It is only applicable if type() is QEasingCurve::InBack, QEasingCurve::OutBack, - QEasingCurve::InOutBack or QEasingCurve::OutInBack. - */ -qreal QEasingCurve::overshoot() const -{ - return d_ptr->config ? d_ptr->config->_o : 1.70158f; -} - -/*! - Sets the overshoot to \a overshoot. - - 0 produces no overshoot, and the default value of 1.70158 produces an overshoot of 10 percent. - - \sa overshoot() -*/ -void QEasingCurve::setOvershoot(qreal overshoot) -{ - if (!d_ptr->config) - d_ptr->config = curveToFunctionObject(d_ptr->type); - d_ptr->config->_o = overshoot; -} - -/*! - Returns the type of the easing curve. -*/ -QEasingCurve::Type QEasingCurve::type() const -{ - return d_ptr->type; -} - -void QEasingCurvePrivate::setType_helper(QEasingCurve::Type newType) -{ - qreal amp = -1.0; - qreal period = -1.0; - qreal overshoot = -1.0; - - if (config) { - amp = config->_a; - period = config->_p; - overshoot = config->_o; - delete config; - config = 0; - } - - if (isConfigFunction(newType) || (amp != -1.0) || (period != -1.0) || (overshoot != -1.0)) { - config = curveToFunctionObject(newType); - if (amp != -1.0) - config->_a = amp; - if (period != -1.0) - config->_p = period; - if (overshoot != -1.0) - config->_o = overshoot; - func = 0; - } else if (newType != QEasingCurve::Custom) { - func = curveToFunc(newType); - } - Q_ASSERT((func == 0) == (config != 0)); - type = newType; -} - -/*! - Sets the type of the easing curve to \a type. -*/ -void QEasingCurve::setType(Type type) -{ - if (d_ptr->type == type) - return; - if (type < Linear || type >= NCurveTypes - 1) { - qWarning("QEasingCurve: Invalid curve type %d", type); - return; - } - - d_ptr->setType_helper(type); -} - -/*! - Sets a custom easing curve that is defined by the user in the function \a func. - The signature of the function is qreal myEasingFunction(qreal progress), - where \e progress and the return value is considered to be normalized between 0 and 1. - (In some cases the return value can be outside that range) - After calling this function type() will return QEasingCurve::Custom. - \a func cannot be zero. - - \sa customType() - \sa valueForProgress() -*/ -void QEasingCurve::setCustomType(EasingFunction func) -{ - if (!func) { - qWarning("Function pointer must not be null"); - return; - } - d_ptr->func = func; - d_ptr->setType_helper(Custom); -} - -/*! - Returns the function pointer to the custom easing curve. - If type() does not return QEasingCurve::Custom, this function - will return 0. -*/ -QEasingCurve::EasingFunction QEasingCurve::customType() const -{ - return d_ptr->type == Custom ? d_ptr->func : 0; -} - -/*! - Return the effective progress for the easing curve at \a progress. - While \a progress must be between 0 and 1, the returned effective progress - can be outside those bounds. For instance, QEasingCurve::InBack will - return negative values in the beginning of the function. - */ -qreal QEasingCurve::valueForProgress(qreal progress) const -{ - progress = qBound(0, progress, 1); - if (d_ptr->func) - return d_ptr->func(progress); - else if (d_ptr->config) - return d_ptr->config->value(progress); - else - return progress; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug debug, const QEasingCurve &item) -{ - debug << "type:" << item.d_ptr->type - << "func:" << item.d_ptr->func; - if (item.d_ptr->config) { - debug << QString::fromAscii("period:%1").arg(item.d_ptr->config->_p, 0, 'f', 20) - << QString::fromAscii("amp:%1").arg(item.d_ptr->config->_a, 0, 'f', 20) - << QString::fromAscii("overshoot:%1").arg(item.d_ptr->config->_o, 0, 'f', 20); - } - return debug; -} -#endif - -QT_END_NAMESPACE diff --git a/src/corelib/tools/qeasingcurve.h b/src/corelib/tools/qeasingcurve.h deleted file mode 100644 index a240bc0..0000000 --- a/src/corelib/tools/qeasingcurve.h +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEASINGCURVE_H -#define QEASINGCURVE_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QEasingCurvePrivate; -class Q_CORE_EXPORT QEasingCurve -{ - Q_GADGET - Q_ENUMS(Type) -public: - enum Type { - Linear, - InQuad, OutQuad, InOutQuad, OutInQuad, - InCubic, OutCubic, InOutCubic, OutInCubic, - InQuart, OutQuart, InOutQuart, OutInQuart, - InQuint, OutQuint, InOutQuint, OutInQuint, - InSine, OutSine, InOutSine, OutInSine, - InExpo, OutExpo, InOutExpo, OutInExpo, - InCirc, OutCirc, InOutCirc, OutInCirc, - InElastic, OutElastic, InOutElastic, OutInElastic, - InBack, OutBack, InOutBack, OutInBack, - InBounce, OutBounce, InOutBounce, OutInBounce, - InCurve, OutCurve, SineCurve, CosineCurve, - Custom, NCurveTypes - }; - - QEasingCurve(Type type = Linear); - QEasingCurve(const QEasingCurve &other); - ~QEasingCurve(); - - QEasingCurve &operator=(const QEasingCurve &other); - bool operator==(const QEasingCurve &other) const; - inline bool operator!=(const QEasingCurve &other) const - { return !(this->operator==(other)); } - - qreal amplitude() const; - void setAmplitude(qreal amplitude); - - qreal period() const; - void setPeriod(qreal period); - - qreal overshoot() const; - void setOvershoot(qreal overshoot); - - Type type() const; - void setType(Type type); - typedef qreal (*EasingFunction)(qreal progress); - void setCustomType(EasingFunction func); - EasingFunction customType() const; - - qreal valueForProgress(qreal progress) const; -private: - QEasingCurvePrivate *d_ptr; - friend Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QEasingCurve &item); -}; - -#ifndef QT_NO_DEBUG_STREAM -Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QEasingCurve &item); -#endif - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index ee4f73c..3a03558 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -48,6 +48,20 @@ QT_BEGIN_NAMESPACE +static const qreal pi = qreal(3.14159265359); +static const qreal halfPi = pi / qreal(2.0); + + +static inline qreal qt_sinProgress(qreal value) +{ + return qSin((value * pi) - halfPi) / 2 + qreal(0.5); +} + +static inline qreal qt_smoothBeginEndMixFactor(qreal value) +{ + return qMin(qMax(1 - value * 2 + qreal(0.3), qreal(0.0)), qreal(1.0)); +} + class QTimeLinePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QTimeLine) @@ -56,7 +70,7 @@ public: : startTime(0), duration(1000), startFrame(0), endFrame(0), updateInterval(1000 / 25), totalLoopCount(1), currentLoopCount(0), currentTime(0), timerId(0), - direction(QTimeLine::Forward), easingCurve(QEasingCurve::InOutSine), + direction(QTimeLine::Forward), curveShape(QTimeLine::EaseInOutCurve), state(QTimeLine::NotRunning) { } @@ -74,7 +88,7 @@ public: QTime timer; QTimeLine::Direction direction; - QEasingCurve easingCurve; + QTimeLine::CurveShape curveShape; QTimeLine::State state; inline void setState(QTimeLine::State newState) { @@ -509,68 +523,12 @@ void QTimeLine::setUpdateInterval(int interval) QTimeLine::CurveShape QTimeLine::curveShape() const { Q_D(const QTimeLine); - switch (d->easingCurve.type()) { - default: - case QEasingCurve::InOutSine: - return EaseInOutCurve; - case QEasingCurve::InCurve: - return EaseInCurve; - case QEasingCurve::OutCurve: - return EaseOutCurve; - case QEasingCurve::Linear: - return LinearCurve; - case QEasingCurve::SineCurve: - return SineCurve; - case QEasingCurve::CosineCurve: - return CosineCurve; - } - return EaseInOutCurve; + return d->curveShape; } - void QTimeLine::setCurveShape(CurveShape shape) { - switch (shape) { - default: - case EaseInOutCurve: - setEasingCurve(QEasingCurve(QEasingCurve::InOutSine)); - break; - case EaseInCurve: - setEasingCurve(QEasingCurve(QEasingCurve::InCurve)); - break; - case EaseOutCurve: - setEasingCurve(QEasingCurve(QEasingCurve::OutCurve)); - break; - case LinearCurve: - setEasingCurve(QEasingCurve(QEasingCurve::Linear)); - break; - case SineCurve: - setEasingCurve(QEasingCurve(QEasingCurve::SineCurve)); - break; - case CosineCurve: - setEasingCurve(QEasingCurve(QEasingCurve::CosineCurve)); - break; - } -} - -/*! - \property QTimeLine::easingCurve - - Specifies the easing curve that the timeline will use. - If both easing curve and curveShape are set, the last set property will - override the previous one. (If valueForTime() is reimplemented it will - override both) -*/ - -QEasingCurve QTimeLine::easingCurve() const -{ - Q_D(const QTimeLine); - return d->easingCurve; -} - -void QTimeLine::setEasingCurve(const QEasingCurve& curve) -{ Q_D(QTimeLine); - d->easingCurve = curve; + d->curveShape = shape; } /*! @@ -650,8 +608,42 @@ qreal QTimeLine::valueForTime(int msec) const Q_D(const QTimeLine); msec = qMin(qMax(msec, 0), d->duration); + // Simple linear interpolation qreal value = msec / qreal(d->duration); - return d->easingCurve.valueForProgress(value); + + switch (d->curveShape) { + case EaseInOutCurve: + value = qt_sinProgress(value); + break; + // SmoothBegin blends Smooth and Linear Interpolation. + // Progress 0 - 0.3 : Smooth only + // Progress 0.3 - ~ 0.5 : Mix of Smooth and Linear + // Progress ~ 0.5 - 1 : Linear only + case EaseInCurve: { + const qreal sinProgress = qt_sinProgress(value); + const qreal linearProgress = value; + const qreal mix = qt_smoothBeginEndMixFactor(value); + value = sinProgress * mix + linearProgress * (1 - mix); + break; + } + case EaseOutCurve: { + const qreal sinProgress = qt_sinProgress(value); + const qreal linearProgress = value; + const qreal mix = qt_smoothBeginEndMixFactor(1 - value); + value = sinProgress * mix + linearProgress * (1 - mix); + break; + } + case SineCurve: + value = (qSin(((msec * pi * 2) / d->duration) - pi/2) + 1) / 2; + break; + case CosineCurve: + value = (qCos(((msec * pi * 2) / d->duration) - pi/2) + 1) / 2; + break; + default: + break; + } + + return value; } /*! diff --git a/src/corelib/tools/qtimeline.h b/src/corelib/tools/qtimeline.h index 48c9232..18c3980 100644 --- a/src/corelib/tools/qtimeline.h +++ b/src/corelib/tools/qtimeline.h @@ -42,7 +42,6 @@ #ifndef QTIMELINE_H #define QTIMELINE_H -#include #include QT_BEGIN_HEADER @@ -61,7 +60,6 @@ class Q_CORE_EXPORT QTimeLine : public QObject Q_PROPERTY(Direction direction READ direction WRITE setDirection) Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount) Q_PROPERTY(CurveShape curveShape READ curveShape WRITE setCurveShape) - Q_PROPERTY(QEasingCurve easingCurve READ easingCurve WRITE setEasingCurve) public: enum State { NotRunning, @@ -107,9 +105,6 @@ public: CurveShape curveShape() const; void setCurveShape(CurveShape shape); - QEasingCurve easingCurve() const; - void setEasingCurve(const QEasingCurve &curve); - int currentTime() const; int currentFrame() const; qreal currentValue() const; diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 90287cb..a6fdac7 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -11,7 +11,6 @@ HEADERS += \ tools/qcryptographichash.h \ tools/qdatetime.h \ tools/qdatetime_p.h \ - tools/qeasingcurve.h \ tools/qhash.h \ tools/qline.h \ tools/qlinkedlist.h \ @@ -47,7 +46,6 @@ SOURCES += \ tools/qbytearraymatcher.cpp \ tools/qcryptographichash.cpp \ tools/qdatetime.cpp \ - tools/qeasingcurve.cpp \ tools/qhash.cpp \ tools/qline.cpp \ tools/qlinkedlist.cpp \ diff --git a/src/gui/animation/animation.pri b/src/gui/animation/animation.pri deleted file mode 100644 index 27763ca..0000000 --- a/src/gui/animation/animation.pri +++ /dev/null @@ -1,3 +0,0 @@ -# Qt gui animation module - -SOURCES += animation/qguivariantanimation.cpp diff --git a/src/gui/animation/qguivariantanimation.cpp b/src/gui/animation/qguivariantanimation.cpp deleted file mode 100644 index 37ca6a1..0000000 --- a/src/gui/animation/qguivariantanimation.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_NO_ANIMATION - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -template<> Q_INLINE_TEMPLATE QColor _q_interpolate(const QColor &f,const QColor &t, qreal progress) -{ - return QColor(_q_interpolate(f.red(), t.red(), progress), - _q_interpolate(f.green(), t.green(), progress), - _q_interpolate(f.blue(), t.blue(), progress), - _q_interpolate(f.alpha(), t.alpha(), progress)); -} - -static int qRegisterGuiGetInterpolator() -{ - qRegisterAnimationInterpolator(_q_interpolateVariant); - return 1; -} -Q_CONSTRUCTOR_FUNCTION(qRegisterGuiGetInterpolator) - -static int qUnregisterGuiGetInterpolator() -{ - qRegisterAnimationInterpolator(0); - return 1; -} -Q_DESTRUCTOR_FUNCTION(qUnregisterGuiGetInterpolator) - -QT_END_NAMESPACE - -#endif //QT_NO_ANIMATION diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 62e0411..b2569c1 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -95,15 +95,6 @@ class Q_AUTOTEST_EXPORT QGraphicsItemPrivate { Q_DECLARE_PUBLIC(QGraphicsItem) public: - struct TransformData - { - TransformData() : rotationX(0),rotationY(0),rotationZ(0),scaleX(1),scaleY(1), dirty(true) {} - QTransform baseTransform; - QTransform transform; - QPointF transformCenter; - qreal rotationX,rotationY,rotationZ,scaleX,scaleY; - bool dirty; - }; enum Extra { ExtraTransform, ExtraToolTip, @@ -248,7 +239,7 @@ public: } } } - + struct ExtraStruct { ExtraStruct(Extra type, QVariant value) : type(type), value(value) @@ -260,7 +251,6 @@ public: bool operator<(Extra extra) const { return type < extra; } }; - QList extras; QGraphicsItemCache *maybeExtraItemCache() const; diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index a5b11ff..01b7593 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -976,7 +976,6 @@ void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *even } #endif // QT_NO_CONTEXTMENU -#ifndef QT_NO_DRAGANDDROP /*! \reimp */ @@ -1097,7 +1096,6 @@ void QGraphicsProxyWidget::dropEvent(QGraphicsSceneDragDropEvent *event) } #endif } -#endif /*! \reimp diff --git a/src/gui/graphicsview/qgraphicsproxywidget.h b/src/gui/graphicsview/qgraphicsproxywidget.h index ab8c9da..b2c3c8f 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.h +++ b/src/gui/graphicsview/qgraphicsproxywidget.h @@ -90,12 +90,10 @@ protected: void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); #endif -#ifndef QT_NO_DRAGANDDROP void dragEnterEvent(QGraphicsSceneDragDropEvent *event); void dragLeaveEvent(QGraphicsSceneDragDropEvent *event); void dragMoveEvent(QGraphicsSceneDragDropEvent *event); void dropEvent(QGraphicsSceneDragDropEvent *event); -#endif void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 329fb01..1aa6558 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -19,7 +19,6 @@ win32:include(kernel/win.pri) embedded:include(embedded/embedded.pri) #modules -include(animation/animation.pri) include(kernel/kernel.pri) include(image/image.pri) include(painting/painting.pri) @@ -32,7 +31,6 @@ include(itemviews/itemviews.pri) include(inputmethod/inputmethod.pri) include(graphicsview/graphicsview.pri) include(util/util.pri) -include(statemachine/statemachine.pri) include(math3d/math3d.pri) embedded: QT += network diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index a9424db..824d6f1 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -838,9 +838,6 @@ void QApplicationPrivate::initialize() // trigger registering of QVariant's GUI types extern int qRegisterGuiVariant(); qRegisterGuiVariant(); - // trigger registering of QStateMachine's GUI types - extern int qRegisterGuiStateMachine(); - qRegisterGuiStateMachine(); is_app_running = true; // no longer starting up @@ -1062,9 +1059,6 @@ QApplication::~QApplication() QApplicationPrivate::fade_tooltip = false; QApplicationPrivate::widgetCount = false; - // trigger unregistering of QStateMachine's GUI types - extern int qUnregisterGuiStateMachine(); - qUnregisterGuiStateMachine(); // trigger unregistering of QVariant's GUI types extern int qUnregisterGuiVariant(); qUnregisterGuiVariant(); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index bbe1a76..fdd0c21 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6930,7 +6930,7 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, } void qt_build_pow_tables() { - qreal smoothing = qreal(1.7); + qreal smoothing = 1.7; #ifdef Q_WS_MAC // decided by testing a few things on an iMac, should probably get this from the @@ -6952,15 +6952,15 @@ void qt_build_pow_tables() { } #else for (int i=0; i<256; ++i) { - qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / qreal(255.0), smoothing) * 255)); - qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / qreal(255.), 1 / smoothing) * 255)); + qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / 255.0, smoothing) * 255)); + qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / 255.0, 1 / smoothing) * 255)); } #endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) const qreal gray_gamma = 2.31; for (int i=0; i<256; ++i) - qt_pow_gamma[i] = uint(qRound(pow(i / qreal(255.), gray_gamma) * 2047)); + qt_pow_gamma[i] = uint(qRound(pow(i / 255.0, gray_gamma) * 2047)); for (int i=0; i<2048; ++i) qt_pow_invgamma[i] = uchar(qRound(pow(i / 2047.0, 1 / gray_gamma) * 255)); #endif diff --git a/src/gui/statemachine/qbasickeyeventtransition.cpp b/src/gui/statemachine/qbasickeyeventtransition.cpp deleted file mode 100644 index f7f1eb6..0000000 --- a/src/gui/statemachine/qbasickeyeventtransition.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbasickeyeventtransition_p.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -/*! - \internal - \class QBasicKeyEventTransition - \since 4.6 - \ingroup statemachine - - \brief The QBasicKeyEventTransition class provides a transition for Qt key events. -*/ - -class QBasicKeyEventTransitionPrivate : public QAbstractTransitionPrivate -{ - Q_DECLARE_PUBLIC(QBasicKeyEventTransition) -public: - QBasicKeyEventTransitionPrivate(); - - static QBasicKeyEventTransitionPrivate *get(QBasicKeyEventTransition *q); - - QEvent::Type eventType; - int key; - Qt::KeyboardModifiers modifiersMask; -}; - -QBasicKeyEventTransitionPrivate::QBasicKeyEventTransitionPrivate() -{ - eventType = QEvent::None; - key = 0; - modifiersMask = Qt::NoModifier; -} - -QBasicKeyEventTransitionPrivate *QBasicKeyEventTransitionPrivate::get(QBasicKeyEventTransition *q) -{ - return q->d_func(); -} - -/*! - Constructs a new key event transition with the given \a sourceState. -*/ -QBasicKeyEventTransition::QBasicKeyEventTransition(QState *sourceState) - : QAbstractTransition(*new QBasicKeyEventTransitionPrivate, sourceState) -{ -} - -/*! - Constructs a new event transition for events of the given \a type for the - given \a key, with the given \a sourceState. -*/ -QBasicKeyEventTransition::QBasicKeyEventTransition(QEvent::Type type, int key, - QState *sourceState) - : QAbstractTransition(*new QBasicKeyEventTransitionPrivate, sourceState) -{ - Q_D(QBasicKeyEventTransition); - d->eventType = type; - d->key = key; -} - -/*! - Constructs a new event transition for events of the given \a type for the - given \a key, with the given \a modifiersMask and \a sourceState. -*/ -QBasicKeyEventTransition::QBasicKeyEventTransition(QEvent::Type type, int key, - Qt::KeyboardModifiers modifiersMask, - QState *sourceState) - : QAbstractTransition(*new QBasicKeyEventTransitionPrivate, sourceState) -{ - Q_D(QBasicKeyEventTransition); - d->eventType = type; - d->key = key; - d->modifiersMask = modifiersMask; -} - -/*! - Destroys this event transition. -*/ -QBasicKeyEventTransition::~QBasicKeyEventTransition() -{ -} - -/*! - Returns the event type that this key event transition is associated with. -*/ -QEvent::Type QBasicKeyEventTransition::eventType() const -{ - Q_D(const QBasicKeyEventTransition); - return d->eventType; -} - -/*! - Sets the event \a type that this key event transition is associated with. -*/ -void QBasicKeyEventTransition::setEventType(QEvent::Type type) -{ - Q_D(QBasicKeyEventTransition); - d->eventType = type; -} - -/*! - Returns the key that this key event transition checks for. -*/ -int QBasicKeyEventTransition::key() const -{ - Q_D(const QBasicKeyEventTransition); - return d->key; -} - -/*! - Sets the key that this key event transition will check for. -*/ -void QBasicKeyEventTransition::setKey(int key) -{ - Q_D(QBasicKeyEventTransition); - d->key = key; -} - -/*! - Returns the keyboard modifiers mask that this key event transition checks - for. -*/ -Qt::KeyboardModifiers QBasicKeyEventTransition::modifiersMask() const -{ - Q_D(const QBasicKeyEventTransition); - return d->modifiersMask; -} - -/*! - Sets the keyboard modifiers mask that this key event transition will check - for. -*/ -void QBasicKeyEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask) -{ - Q_D(QBasicKeyEventTransition); - d->modifiersMask = modifiersMask; -} - -/*! - \reimp -*/ -bool QBasicKeyEventTransition::eventTest(QEvent *event) -{ - Q_D(const QBasicKeyEventTransition); - if (event->type() == d->eventType) { - QKeyEvent *ke = static_cast(event); - return (ke->key() == d->key) - && ((ke->modifiers() & d->modifiersMask) == d->modifiersMask); - } - return false; -} - -/*! - \reimp -*/ -void QBasicKeyEventTransition::onTransition(QEvent *) -{ -} - -QT_END_NAMESPACE diff --git a/src/gui/statemachine/qbasickeyeventtransition_p.h b/src/gui/statemachine/qbasickeyeventtransition_p.h deleted file mode 100644 index 39fa6ad..0000000 --- a/src/gui/statemachine/qbasickeyeventtransition_p.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBASICKEYEVENTTRANSITION_P_H -#define QBASICKEYEVENTTRANSITION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include - -QT_BEGIN_NAMESPACE - -class QBasicKeyEventTransitionPrivate; -class Q_AUTOTEST_EXPORT QBasicKeyEventTransition : public QAbstractTransition -{ - Q_OBJECT -public: - QBasicKeyEventTransition(QState *sourceState = 0); - QBasicKeyEventTransition(QEvent::Type type, int key, QState *sourceState = 0); - QBasicKeyEventTransition(QEvent::Type type, int key, - Qt::KeyboardModifiers modifiersMask, - QState *sourceState = 0); - ~QBasicKeyEventTransition(); - - QEvent::Type eventType() const; - void setEventType(QEvent::Type type); - - int key() const; - void setKey(int key); - - Qt::KeyboardModifiers modifiersMask() const; - void setModifiersMask(Qt::KeyboardModifiers modifiers); - -protected: - bool eventTest(QEvent *event); - void onTransition(QEvent *); - -private: - Q_DISABLE_COPY(QBasicKeyEventTransition) - Q_DECLARE_PRIVATE(QBasicKeyEventTransition) -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/gui/statemachine/qbasicmouseeventtransition.cpp b/src/gui/statemachine/qbasicmouseeventtransition.cpp deleted file mode 100644 index 20dd792..0000000 --- a/src/gui/statemachine/qbasicmouseeventtransition.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbasicmouseeventtransition_p.h" -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -/*! - \internal - \class QBasicMouseEventTransition - \since 4.6 - \ingroup statemachine - - \brief The QBasicMouseEventTransition class provides a transition for Qt mouse events. -*/ - -class QBasicMouseEventTransitionPrivate : public QAbstractTransitionPrivate -{ - Q_DECLARE_PUBLIC(QBasicMouseEventTransition) -public: - QBasicMouseEventTransitionPrivate(); - - static QBasicMouseEventTransitionPrivate *get(QBasicMouseEventTransition *q); - - QEvent::Type eventType; - Qt::MouseButton button; - Qt::KeyboardModifiers modifiersMask; - QPainterPath path; -}; - -QBasicMouseEventTransitionPrivate::QBasicMouseEventTransitionPrivate() -{ - eventType = QEvent::None; - button = Qt::NoButton; -} - -QBasicMouseEventTransitionPrivate *QBasicMouseEventTransitionPrivate::get(QBasicMouseEventTransition *q) -{ - return q->d_func(); -} - -/*! - Constructs a new mouse event transition with the given \a sourceState. -*/ -QBasicMouseEventTransition::QBasicMouseEventTransition(QState *sourceState) - : QAbstractTransition(*new QBasicMouseEventTransitionPrivate, sourceState) -{ -} - -/*! - Constructs a new mouse event transition for events of the given \a type. -*/ -QBasicMouseEventTransition::QBasicMouseEventTransition(QEvent::Type type, - Qt::MouseButton button, - QState *sourceState) - : QAbstractTransition(*new QBasicMouseEventTransitionPrivate, sourceState) -{ - Q_D(QBasicMouseEventTransition); - d->eventType = type; - d->button = button; -} - -/*! - Destroys this mouse event transition. -*/ -QBasicMouseEventTransition::~QBasicMouseEventTransition() -{ -} - -/*! - Returns the event type that this mouse event transition is associated with. -*/ -QEvent::Type QBasicMouseEventTransition::eventType() const -{ - Q_D(const QBasicMouseEventTransition); - return d->eventType; -} - -/*! - Sets the event \a type that this mouse event transition is associated with. -*/ -void QBasicMouseEventTransition::setEventType(QEvent::Type type) -{ - Q_D(QBasicMouseEventTransition); - d->eventType = type; -} - -/*! - Returns the button that this mouse event transition checks for. -*/ -Qt::MouseButton QBasicMouseEventTransition::button() const -{ - Q_D(const QBasicMouseEventTransition); - return d->button; -} - -/*! - Sets the button that this mouse event transition will check for. -*/ -void QBasicMouseEventTransition::setButton(Qt::MouseButton button) -{ - Q_D(QBasicMouseEventTransition); - d->button = button; -} - -/*! - Returns the keyboard modifiers mask that this mouse event transition checks - for. -*/ -Qt::KeyboardModifiers QBasicMouseEventTransition::modifiersMask() const -{ - Q_D(const QBasicMouseEventTransition); - return d->modifiersMask; -} - -/*! - Sets the keyboard modifiers mask that this mouse event transition will check - for. -*/ -void QBasicMouseEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask) -{ - Q_D(QBasicMouseEventTransition); - d->modifiersMask = modifiersMask; -} - -/*! - Returns the path for this mouse event transition. -*/ -QPainterPath QBasicMouseEventTransition::path() const -{ - Q_D(const QBasicMouseEventTransition); - return d->path; -} - -/*! - Sets the path for this mouse event transition. -*/ -void QBasicMouseEventTransition::setPath(const QPainterPath &path) -{ - Q_D(QBasicMouseEventTransition); - d->path = path; -} - -/*! - \reimp -*/ -bool QBasicMouseEventTransition::eventTest(QEvent *event) -{ - Q_D(const QBasicMouseEventTransition); - if (event->type() == d->eventType) { - QMouseEvent *me = static_cast(event); - return (me->button() == d->button) - && ((me->modifiers() & d->modifiersMask) == d->modifiersMask) - && (d->path.isEmpty() || d->path.contains(me->pos())); - } - return false; -} - -/*! - \reimp -*/ -void QBasicMouseEventTransition::onTransition(QEvent *) -{ -} - -QT_END_NAMESPACE diff --git a/src/gui/statemachine/qbasicmouseeventtransition_p.h b/src/gui/statemachine/qbasicmouseeventtransition_p.h deleted file mode 100644 index 6c0afe4..0000000 --- a/src/gui/statemachine/qbasicmouseeventtransition_p.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBASICMOUSEEVENTTRANSITION_P_H -#define QBASICMOUSEEVENTTRANSITION_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include - -QT_BEGIN_NAMESPACE - -class QPainterPath; - -class QBasicMouseEventTransitionPrivate; -class Q_AUTOTEST_EXPORT QBasicMouseEventTransition : public QAbstractTransition -{ - Q_OBJECT -public: - QBasicMouseEventTransition(QState *sourceState = 0); - QBasicMouseEventTransition(QEvent::Type type, Qt::MouseButton button, - QState *sourceState = 0); - ~QBasicMouseEventTransition(); - - QEvent::Type eventType() const; - void setEventType(QEvent::Type type); - - Qt::MouseButton button() const; - void setButton(Qt::MouseButton button); - - Qt::KeyboardModifiers modifiersMask() const; - void setModifiersMask(Qt::KeyboardModifiers modifiers); - - QPainterPath path() const; - void setPath(const QPainterPath &path); - -protected: - bool eventTest(QEvent *event); - void onTransition(QEvent *); - -private: - Q_DISABLE_COPY(QBasicMouseEventTransition) - Q_DECLARE_PRIVATE(QBasicMouseEventTransition) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp deleted file mode 100644 index 612e43e..0000000 --- a/src/gui/statemachine/qguistatemachine.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -Q_CORE_EXPORT const QStateMachinePrivate::Handler *qcoreStateMachineHandler(); - -static QEvent *cloneEvent(QEvent *e) -{ - switch (e->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::MouseMove: - return new QMouseEvent(*static_cast(e)); - case QEvent::KeyPress: - case QEvent::KeyRelease: - return new QKeyEvent(*static_cast(e)); - case QEvent::FocusIn: - case QEvent::FocusOut: - return new QFocusEvent(*static_cast(e)); - case QEvent::Enter: - return new QEvent(*e); - case QEvent::Leave: - return new QEvent(*e); - break; - case QEvent::Paint: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::Move: - return new QMoveEvent(*static_cast(e)); - case QEvent::Resize: - return new QResizeEvent(*static_cast(e)); - case QEvent::Create: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::Destroy: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::Show: - return new QShowEvent(*static_cast(e)); - case QEvent::Hide: - return new QHideEvent(*static_cast(e)); - case QEvent::Close: - return new QCloseEvent(*static_cast(e)); - case QEvent::Quit: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ParentChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ParentAboutToChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ThreadChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::WindowActivate: - case QEvent::WindowDeactivate: - return new QEvent(*e); - - case QEvent::ShowToParent: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::HideToParent: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::Wheel: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::WindowTitleChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::WindowIconChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ApplicationWindowIconChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ApplicationFontChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ApplicationLayoutDirectionChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ApplicationPaletteChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::PaletteChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::Clipboard: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::Speech: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::MetaCall: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::SockAct: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::WinEventAct: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::DeferredDelete: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::DragEnter: - return new QDragEnterEvent(*static_cast(e)); - case QEvent::DragMove: - return new QDragMoveEvent(*static_cast(e)); - case QEvent::DragLeave: - return new QDragLeaveEvent(*static_cast(e)); - case QEvent::Drop: - return new QDropEvent(*static_cast(e)); - case QEvent::DragResponse: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ChildAdded: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ChildPolished: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; -#ifdef QT3_SUPPORT - case QEvent::ChildInsertedRequest: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ChildInserted: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::LayoutHint: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; -#endif - case QEvent::ChildRemoved: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ShowWindowRequest: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::PolishRequest: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::Polish: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::LayoutRequest: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::UpdateRequest: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::UpdateLater: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::EmbeddingControl: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ActivateControl: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::DeactivateControl: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ContextMenu: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::InputMethod: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::AccessibilityPrepare: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::TabletMove: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::LocaleChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::LanguageChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::LayoutDirectionChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::Style: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::TabletPress: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::TabletRelease: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::OkRequest: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::HelpRequest: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::IconDrag: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::FontChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::EnabledChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ActivationChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::StyleChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::IconTextChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ModifiedChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::MouseTrackingChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::WindowBlocked: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::WindowUnblocked: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::WindowStateChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::ToolTip: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::WhatsThis: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::StatusTip: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::ActionChanged: - case QEvent::ActionAdded: - case QEvent::ActionRemoved: - return new QActionEvent(*static_cast(e)); - - case QEvent::FileOpen: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::Shortcut: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ShortcutOverride: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - -#ifdef QT3_SUPPORT - case QEvent::Accel: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::AccelAvailable: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; -#endif - - case QEvent::WhatsThisClicked: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::ToolBarChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::ApplicationActivate: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ApplicationDeactivate: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::QueryWhatsThis: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::EnterWhatsThisMode: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::LeaveWhatsThisMode: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::ZOrderChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::HoverEnter: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::HoverLeave: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::HoverMove: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::AccessibilityHelp: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::AccessibilityDescription: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - -#ifdef QT_KEYPAD_NAVIGATION - case QEvent::EnterEditFocus: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::LeaveEditFocus: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; -#endif - case QEvent::AcceptDropsChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::MenubarUpdated: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::ZeroTimerEvent: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::GraphicsSceneMouseMove: - case QEvent::GraphicsSceneMousePress: - case QEvent::GraphicsSceneMouseRelease: - case QEvent::GraphicsSceneMouseDoubleClick: { - QGraphicsSceneMouseEvent *me = static_cast(e); - QGraphicsSceneMouseEvent *me2 = new QGraphicsSceneMouseEvent(me->type()); - me2->setWidget(me->widget()); - me2->setPos(me->pos()); - me2->setScenePos(me->scenePos()); - me2->setScreenPos(me->screenPos()); -// ### for all buttons - me2->setButtonDownPos(Qt::LeftButton, me->buttonDownPos(Qt::LeftButton)); - me2->setButtonDownPos(Qt::RightButton, me->buttonDownPos(Qt::RightButton)); - me2->setButtonDownScreenPos(Qt::LeftButton, me->buttonDownScreenPos(Qt::LeftButton)); - me2->setButtonDownScreenPos(Qt::RightButton, me->buttonDownScreenPos(Qt::RightButton)); - me2->setLastPos(me->lastPos()); - me2->setLastScenePos(me->lastScenePos()); - me2->setLastScreenPos(me->lastScreenPos()); - me2->setButtons(me->buttons()); - me2->setButton(me->button()); - me2->setModifiers(me->modifiers()); - return me2; - } - - case QEvent::GraphicsSceneContextMenu: { - QGraphicsSceneContextMenuEvent *me = static_cast(e); - QGraphicsSceneContextMenuEvent *me2 = new QGraphicsSceneContextMenuEvent(me->type()); - me2->setWidget(me->widget()); - me2->setPos(me->pos()); - me2->setScenePos(me->scenePos()); - me2->setScreenPos(me->screenPos()); - me2->setModifiers(me->modifiers()); - me2->setReason(me->reason()); - return me2; - } - - case QEvent::GraphicsSceneHoverEnter: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::GraphicsSceneHoverMove: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::GraphicsSceneHoverLeave: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::GraphicsSceneHelp: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::GraphicsSceneDragEnter: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::GraphicsSceneDragMove: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::GraphicsSceneDragLeave: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::GraphicsSceneDrop: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::GraphicsSceneWheel: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::KeyboardLayoutChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::DynamicPropertyChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::TabletEnterProximity: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::TabletLeaveProximity: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::NonClientAreaMouseMove: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::NonClientAreaMouseButtonPress: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::NonClientAreaMouseButtonRelease: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::NonClientAreaMouseButtonDblClick: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::MacSizeChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::ContentsRectChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::MacGLWindowChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::FutureCallOut: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::GraphicsSceneResize: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::GraphicsSceneMove: { - QGraphicsSceneMoveEvent *me = static_cast(e); - QGraphicsSceneMoveEvent *me2 = new QGraphicsSceneMoveEvent(); - me2->setWidget(me->widget()); - me2->setNewPos(me->newPos()); - me2->setOldPos(me->oldPos()); - return me2; - } - - case QEvent::CursorChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - case QEvent::ToolTipChange: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::NetworkReplyUpdated: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - - case QEvent::GrabMouse: - case QEvent::UngrabMouse: - case QEvent::GrabKeyboard: - case QEvent::UngrabKeyboard: - return new QEvent(*e); - -#ifdef QT_MAC_USE_COCOA - case QEvent::CocoaRequestModal: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; -#endif - case QEvent::User: - case QEvent::MaxUser: - Q_ASSERT_X(false, "cloneEvent()", "not implemented"); - break; - default: - ; - } - return qcoreStateMachineHandler()->cloneEvent(e); -} - -const QStateMachinePrivate::Handler qt_gui_statemachine_handler = { - cloneEvent -}; - -static const QStateMachinePrivate::Handler *qt_guistatemachine_last_handler = 0; -int qRegisterGuiStateMachine() -{ - qt_guistatemachine_last_handler = QStateMachinePrivate::handler; - QStateMachinePrivate::handler = &qt_gui_statemachine_handler; - return 1; -} -Q_CONSTRUCTOR_FUNCTION(qRegisterGuiStateMachine) - -int qUnregisterGuiStateMachine() -{ - QStateMachinePrivate::handler = qt_guistatemachine_last_handler; - return 1; -} -Q_DESTRUCTOR_FUNCTION(qUnregisterGuiStateMachine) - -QT_END_NAMESPACE diff --git a/src/gui/statemachine/qkeyeventtransition.cpp b/src/gui/statemachine/qkeyeventtransition.cpp deleted file mode 100644 index f803711..0000000 --- a/src/gui/statemachine/qkeyeventtransition.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qkeyeventtransition.h" -#include "qbasickeyeventtransition_p.h" -#include -#include - -QT_BEGIN_NAMESPACE - -/*! - \class QKeyEventTransition - - \brief The QKeyEventTransition class provides a transition for key events. - - \since 4.6 - \ingroup statemachine - - QKeyEventTransition is part of \l{The State Machine Framework}. - - \sa QState::addTransition() -*/ - -/*! - \property QKeyEventTransition::key - - \brief the key that this key event transition is associated with -*/ - -/*! - \property QKeyEventTransition::modifiersMask - - \brief the keyboard modifiers mask that this key event transition checks for -*/ - -class QKeyEventTransitionPrivate : public QEventTransitionPrivate -{ - Q_DECLARE_PUBLIC(QKeyEventTransition) -public: - QKeyEventTransitionPrivate() {} - - QBasicKeyEventTransition *transition; -}; - -/*! - Constructs a new key event transition with the given \a sourceState. -*/ -QKeyEventTransition::QKeyEventTransition(QState *sourceState) - : QEventTransition(*new QKeyEventTransitionPrivate, sourceState) -{ - Q_D(QKeyEventTransition); - d->transition = new QBasicKeyEventTransition(); -} - -/*! - Constructs a new key event transition for events of the given \a type for - the given \a object, with the given \a key and \a sourceState. -*/ -QKeyEventTransition::QKeyEventTransition(QObject *object, QEvent::Type type, - int key, QState *sourceState) - : QEventTransition(*new QKeyEventTransitionPrivate, object, type, sourceState) -{ - Q_D(QKeyEventTransition); - d->transition = new QBasicKeyEventTransition(type, key); -} - -/*! - Constructs a new key event transition for events of the given \a type for - the given \a object, with the given \a key, \a targets and \a sourceState. -*/ -QKeyEventTransition::QKeyEventTransition(QObject *object, QEvent::Type type, - int key, const QList &targets, - QState *sourceState) - : QEventTransition(*new QKeyEventTransitionPrivate, object, type, targets, sourceState) -{ - Q_D(QKeyEventTransition); - d->transition = new QBasicKeyEventTransition(type, key); -} - -/*! - Destroys this key event transition. -*/ -QKeyEventTransition::~QKeyEventTransition() -{ - Q_D(QKeyEventTransition); - delete d->transition; -} - -/*! - Returns the key that this key event transition checks for. -*/ -int QKeyEventTransition::key() const -{ - Q_D(const QKeyEventTransition); - return d->transition->key(); -} - -/*! - Sets the key that this key event transition will check for. -*/ -void QKeyEventTransition::setKey(int key) -{ - Q_D(QKeyEventTransition); - d->transition->setKey(key); -} - -/*! - Returns the keyboard modifiers mask that this key event transition checks - for. -*/ -Qt::KeyboardModifiers QKeyEventTransition::modifiersMask() const -{ - Q_D(const QKeyEventTransition); - return d->transition->modifiersMask(); -} - -/*! - Sets the keyboard \a modifiers mask that this key event transition will - check for. -*/ -void QKeyEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask) -{ - Q_D(QKeyEventTransition); - d->transition->setModifiersMask(modifiersMask); -} - -/*! - \reimp -*/ -bool QKeyEventTransition::eventTest(QEvent *event) -{ - Q_D(const QKeyEventTransition); - if (!QEventTransition::eventTest(event)) - return false; - QWrappedEvent *we = static_cast(event); - d->transition->setEventType(we->event()->type()); - return QAbstractTransitionPrivate::get(d->transition)->callEventTest(we->event()); -} - -/*! - \reimp -*/ -void QKeyEventTransition::onTransition(QEvent *event) -{ - QEventTransition::onTransition(event); -} - -QT_END_NAMESPACE diff --git a/src/gui/statemachine/qkeyeventtransition.h b/src/gui/statemachine/qkeyeventtransition.h deleted file mode 100644 index 3c8295f..0000000 --- a/src/gui/statemachine/qkeyeventtransition.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QKEYEVENTTRANSITION_H -#define QKEYEVENTTRANSITION_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QKeyEventTransitionPrivate; -class Q_GUI_EXPORT QKeyEventTransition : public QEventTransition -{ - Q_OBJECT - Q_PROPERTY(int key READ key WRITE setKey) - Q_PROPERTY(Qt::KeyboardModifiers modifiersMask READ modifiersMask WRITE setModifiersMask) -public: - QKeyEventTransition(QState *sourceState = 0); - QKeyEventTransition(QObject *object, QEvent::Type type, int key, - QState *sourceState = 0); - QKeyEventTransition(QObject *object, QEvent::Type type, int key, - const QList &targets, - QState *sourceState = 0); - ~QKeyEventTransition(); - - int key() const; - void setKey(int key); - - Qt::KeyboardModifiers modifiersMask() const; - void setModifiersMask(Qt::KeyboardModifiers modifiers); - -protected: - void onTransition(QEvent *event); - bool eventTest(QEvent *event); - -private: - Q_DISABLE_COPY(QKeyEventTransition) - Q_DECLARE_PRIVATE(QKeyEventTransition) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/gui/statemachine/qmouseeventtransition.cpp b/src/gui/statemachine/qmouseeventtransition.cpp deleted file mode 100644 index e4e18eb..0000000 --- a/src/gui/statemachine/qmouseeventtransition.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmouseeventtransition.h" -#include "qbasicmouseeventtransition_p.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -/*! - \class QMouseEventTransition - - \brief The QMouseEventTransition class provides a transition for mouse events. - - \since 4.6 - \ingroup statemachine - - QMouseEventTransition is part of \l{The State Machine Framework}. - - \sa QState::addTransition() -*/ - -/*! - \property QMouseEventTransition::button - - \brief the button that this mouse event transition is associated with -*/ - -/*! - \property QMouseEventTransition::modifiersMask - - \brief the keyboard modifiers mask that this mouse event transition checks for -*/ - -class QMouseEventTransitionPrivate : public QEventTransitionPrivate -{ - Q_DECLARE_PUBLIC(QMouseEventTransition) -public: - QMouseEventTransitionPrivate(); - - QBasicMouseEventTransition *transition; -}; - -QMouseEventTransitionPrivate::QMouseEventTransitionPrivate() -{ -} - -/*! - Constructs a new mouse event transition with the given \a sourceState. -*/ -QMouseEventTransition::QMouseEventTransition(QState *sourceState) - : QEventTransition(*new QMouseEventTransitionPrivate, sourceState) -{ - Q_D(QMouseEventTransition); - d->transition = new QBasicMouseEventTransition(); -} - -/*! - Constructs a new mouse event transition for events of the given \a type for - the given \a object, with the given \a button and \a sourceState. -*/ -QMouseEventTransition::QMouseEventTransition(QObject *object, QEvent::Type type, - Qt::MouseButton button, - QState *sourceState) - : QEventTransition(*new QMouseEventTransitionPrivate, object, type, sourceState) -{ - Q_D(QMouseEventTransition); - d->transition = new QBasicMouseEventTransition(type, button); -} - -/*! - Constructs a new mouse event transition for events of the given \a type for - the given \a object, with the given \a button, \a targets and \a - sourceState. -*/ -QMouseEventTransition::QMouseEventTransition(QObject *object, QEvent::Type type, - Qt::MouseButton button, - const QList &targets, - QState *sourceState) - : QEventTransition(*new QMouseEventTransitionPrivate, object, type, targets, sourceState) -{ - Q_D(QMouseEventTransition); - d->transition = new QBasicMouseEventTransition(type, button); -} - -/*! - Destroys this mouse event transition. -*/ -QMouseEventTransition::~QMouseEventTransition() -{ - Q_D(QMouseEventTransition); - delete d->transition; -} - -/*! - Returns the button that this mouse event transition checks for. -*/ -Qt::MouseButton QMouseEventTransition::button() const -{ - Q_D(const QMouseEventTransition); - return d->transition->button(); -} - -/*! - Sets the \a button that this mouse event transition will check for. -*/ -void QMouseEventTransition::setButton(Qt::MouseButton button) -{ - Q_D(QMouseEventTransition); - d->transition->setButton(button); -} - -/*! - Returns the keyboard modifiers mask that this mouse event transition checks - for. -*/ -Qt::KeyboardModifiers QMouseEventTransition::modifiersMask() const -{ - Q_D(const QMouseEventTransition); - return d->transition->modifiersMask(); -} - -/*! - Sets the keyboard \a modifiers mask that this mouse event transition will - check for. -*/ -void QMouseEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask) -{ - Q_D(QMouseEventTransition); - d->transition->setModifiersMask(modifiersMask); -} - -/*! - Returns the path for this mouse event transition. -*/ -QPainterPath QMouseEventTransition::path() const -{ - Q_D(const QMouseEventTransition); - return d->transition->path(); -} - -/*! - Sets the \a path for this mouse event transition. - If a valid path has been set, the transition will only trigger if the mouse - event position (QMouseEvent::pos()) is inside the path. - - \sa QPainterPath::contains() -*/ -void QMouseEventTransition::setPath(const QPainterPath &path) -{ - Q_D(QMouseEventTransition); - d->transition->setPath(path); -} - -/*! - \reimp -*/ -bool QMouseEventTransition::eventTest(QEvent *event) -{ - Q_D(const QMouseEventTransition); - if (!QEventTransition::eventTest(event)) - return false; - QWrappedEvent *we = static_cast(event); - d->transition->setEventType(we->event()->type()); - return QAbstractTransitionPrivate::get(d->transition)->callEventTest(we->event()); -} - -/*! - \reimp -*/ -void QMouseEventTransition::onTransition(QEvent *event) -{ - QEventTransition::onTransition(event); -} - -QT_END_NAMESPACE diff --git a/src/gui/statemachine/qmouseeventtransition.h b/src/gui/statemachine/qmouseeventtransition.h deleted file mode 100644 index 3f5f3ac..0000000 --- a/src/gui/statemachine/qmouseeventtransition.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMOUSEEVENTTRANSITION_H -#define QMOUSEEVENTTRANSITION_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -class QMouseEventTransitionPrivate; -class QPainterPath; -class Q_GUI_EXPORT QMouseEventTransition : public QEventTransition -{ - Q_OBJECT - Q_PROPERTY(Qt::MouseButton button READ button WRITE setButton) - Q_PROPERTY(Qt::KeyboardModifiers modifiersMask READ modifiersMask WRITE setModifiersMask) -public: - QMouseEventTransition(QState *sourceState = 0); - QMouseEventTransition(QObject *object, QEvent::Type type, - Qt::MouseButton button, QState *sourceState = 0); - QMouseEventTransition(QObject *object, QEvent::Type type, - Qt::MouseButton button, - const QList &targets, - QState *sourceState = 0); - ~QMouseEventTransition(); - - Qt::MouseButton button() const; - void setButton(Qt::MouseButton button); - - Qt::KeyboardModifiers modifiersMask() const; - void setModifiersMask(Qt::KeyboardModifiers modifiers); - - QPainterPath path() const; - void setPath(const QPainterPath &path); - -protected: - void onTransition(QEvent *event); - bool eventTest(QEvent *event); - -private: - Q_DISABLE_COPY(QMouseEventTransition) - Q_DECLARE_PRIVATE(QMouseEventTransition) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/gui/statemachine/statemachine.pri b/src/gui/statemachine/statemachine.pri deleted file mode 100644 index 2eb1e05..0000000 --- a/src/gui/statemachine/statemachine.pri +++ /dev/null @@ -1,13 +0,0 @@ -SOURCES += $$PWD/qguistatemachine.cpp -!contains(DEFINES, QT_NO_STATEMACHINE_EVENTFILTER) { - HEADERS += \ - $$PWD/qkeyeventtransition.h \ - $$PWD/qmouseeventtransition.h \ - $$PWD/qbasickeyeventtransition_p.h \ - $$PWD/qbasicmouseeventtransition_p.h - SOURCES += \ - $$PWD/qkeyeventtransition.cpp \ - $$PWD/qmouseeventtransition.cpp \ - $$PWD/qbasickeyeventtransition.cpp \ - $$PWD/qbasicmouseeventtransition.cpp -} diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 316a695..714e19d 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -75,7 +75,6 @@ SUBDIRS += bic \ qaction \ qactiongroup \ qalgorithms \ - qanimationgroup \ qapplication \ qatomicint \ qatomicpointer \ @@ -215,7 +214,6 @@ SUBDIRS += bic \ qpainter \ qpainterpath \ qpalette \ - qparallelanimationgroup \ qpathclipper \ qpen \ qpicture \ @@ -231,7 +229,6 @@ SUBDIRS += bic \ qprocess \ qprogressbar \ qprogressdialog \ - qpropertyanimation \ qpushbutton \ qqueue \ qradiobutton \ @@ -259,7 +256,6 @@ SUBDIRS += bic \ qscrollarea \ qsemaphore \ qsharedpointer \ - qsequentialanimationgroup \ qset \ qsettings \ qshortcut \ @@ -293,7 +289,6 @@ SUBDIRS += bic \ qstackedwidget \ qstandarditem \ qstandarditemmodel \ - qstate \ qstatusbar \ qstl \ qstring \ @@ -347,7 +342,6 @@ SUBDIRS += bic \ qtranslator \ qtransform \ qtransformedscreen \ - qtransition \ qtreeview \ qtreewidget \ qtreewidgetitemiterator \ diff --git a/tests/auto/qanimationgroup/qanimationgroup.pro b/tests/auto/qanimationgroup/qanimationgroup.pro deleted file mode 100644 index 97d33dd..0000000 --- a/tests/auto/qanimationgroup/qanimationgroup.pro +++ /dev/null @@ -1,5 +0,0 @@ -load(qttest_p4) -QT = core gui -SOURCES += tst_qanimationgroup.cpp - - diff --git a/tests/auto/qanimationgroup/tst_qanimationgroup.cpp b/tests/auto/qanimationgroup/tst_qanimationgroup.cpp deleted file mode 100644 index 2952a39..0000000 --- a/tests/auto/qanimationgroup/tst_qanimationgroup.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include -#include - -//TESTED_CLASS=QAnimationGroup -//TESTED_FILES= - -Q_DECLARE_METATYPE(QAbstractAnimation::State) - -class tst_QAnimationGroup : public QObject -{ - Q_OBJECT -public: - tst_QAnimationGroup(); - virtual ~tst_QAnimationGroup(); - -public Q_SLOTS: - void init(); - void cleanup(); - -private slots: - void construction(); - void emptyGroup(); - void setCurrentTime(); - void statesAndSignals(); - void setParentAutoAdd(); - void beginNestedGroup(); - void addChildTwice(); - void loopWithoutStartValue(); -}; - -tst_QAnimationGroup::tst_QAnimationGroup() -{ -} - -tst_QAnimationGroup::~tst_QAnimationGroup() -{ -} - -void tst_QAnimationGroup::init() -{ - qRegisterMetaType("QAbstractAnimation::State"); -} - -void tst_QAnimationGroup::cleanup() -{ -} - -void tst_QAnimationGroup::construction() -{ - QSequentialAnimationGroup animationgroup; -} - -class AnimationObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(int value READ value WRITE setValue) -public: - AnimationObject(int startValue = 0) - : v(startValue) - { } - - int value() const { return v; } - void setValue(int value) { v = value; } - - int v; -}; - -class TestAnimation : public QVariantAnimation -{ - Q_OBJECT -public: - virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)}; - virtual void updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) - { - Q_UNUSED(oldState) - Q_UNUSED(newState) - }; -}; - -class UncontrolledAnimation : public QPropertyAnimation -{ - Q_OBJECT -public: - UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0) - : QPropertyAnimation(target, propertyName, parent), id(0) - { - setDuration(250); - } - - int duration() const { return -1; /* not time driven */ } - -protected: - void timerEvent(QTimerEvent *event) - { - if (event->timerId() == id) - stop(); - } - - void updateRunning(bool running) - { - if (running) { - id = startTimer(500); - } else { - killTimer(id); - id = 0; - } - } - -private: - int id; -}; - -void tst_QAnimationGroup::emptyGroup() -{ - QSequentialAnimationGroup group; - QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - group.start(); - - QCOMPARE(groupStateChangedSpy.count(), 2); - - QCOMPARE(qVariantValue(groupStateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(groupStateChangedSpy.at(1).at(1)), - QAnimationGroup::Stopped); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - - QTest::ignoreMessage(QtWarningMsg, "QAbstractAnimation::pause: Cannot pause a stopped animation"); - group.pause(); - - QCOMPARE(groupStateChangedSpy.count(), 2); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - - group.start(); - - QCOMPARE(qVariantValue(groupStateChangedSpy.at(2).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(groupStateChangedSpy.at(3).at(1)), - QAnimationGroup::Stopped); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - - group.stop(); - - QCOMPARE(groupStateChangedSpy.count(), 4); - QCOMPARE(group.state(), QAnimationGroup::Stopped); -} - -void tst_QAnimationGroup::setCurrentTime() -{ - AnimationObject s_o1; - AnimationObject s_o2; - AnimationObject s_o3; - AnimationObject p_o1; - AnimationObject p_o2; - AnimationObject p_o3; - AnimationObject t_o1; - AnimationObject t_o2; - - // sequence operating on same object/property - QSequentialAnimationGroup *sequence = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setLoopCount(3); - sequence->addAnimation(a1_s_o1); - sequence->addAnimation(a2_s_o1); - sequence->addAnimation(a3_s_o1); - - // sequence operating on different object/properties - QAnimationGroup *sequence2 = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); - QVariantAnimation *a1_s_o3 = new QPropertyAnimation(&s_o3, "value"); - sequence2->addAnimation(a1_s_o2); - sequence2->addAnimation(a1_s_o3); - - // parallel operating on different object/properties - QAnimationGroup *parallel = new QParallelAnimationGroup(); - QVariantAnimation *a1_p_o1 = new QPropertyAnimation(&p_o1, "value"); - QVariantAnimation *a1_p_o2 = new QPropertyAnimation(&p_o2, "value"); - QVariantAnimation *a1_p_o3 = new QPropertyAnimation(&p_o3, "value"); - a1_p_o2->setLoopCount(3); - parallel->addAnimation(a1_p_o1); - parallel->addAnimation(a1_p_o2); - parallel->addAnimation(a1_p_o3); - - UncontrolledAnimation *notTimeDriven = new UncontrolledAnimation(&t_o1, "value"); - QCOMPARE(notTimeDriven->totalDuration(), -1); - - QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value"); - loopsForever->setLoopCount(-1); - QCOMPARE(loopsForever->totalDuration(), -1); - - QParallelAnimationGroup group; - group.addAnimation(sequence); - group.addAnimation(sequence2); - group.addAnimation(parallel); - group.addAnimation(notTimeDriven); - group.addAnimation(loopsForever); - - // Current time = 1 - group.setCurrentTime(1); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(sequence->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(parallel->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_p_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_p_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_p_o3->state(), QAnimationGroup::Stopped); - QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); - QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); - - QCOMPARE(group.currentTime(), 1); - QCOMPARE(sequence->currentTime(), 1); - QCOMPARE(a1_s_o1->currentTime(), 1); - QCOMPARE(a2_s_o1->currentTime(), 0); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 1); - QCOMPARE(a1_s_o3->currentTime(), 0); - QCOMPARE(a1_p_o1->currentTime(), 1); - QCOMPARE(a1_p_o2->currentTime(), 1); - QCOMPARE(a1_p_o3->currentTime(), 1); - QCOMPARE(notTimeDriven->currentTime(), 1); - QCOMPARE(loopsForever->currentTime(), 1); - - // Current time = 250 - group.setCurrentTime(250); - QCOMPARE(group.currentTime(), 250); - QCOMPARE(sequence->currentTime(), 250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 0); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(a1_s_o3->currentTime(), 0); - QCOMPARE(a1_p_o1->currentTime(), 250); - QCOMPARE(a1_p_o2->currentTime(), 0); - QCOMPARE(a1_p_o2->currentLoop(), 1); - QCOMPARE(a1_p_o3->currentTime(), 250); - QCOMPARE(notTimeDriven->currentTime(), 250); - QCOMPARE(loopsForever->currentTime(), 0); - QCOMPARE(loopsForever->currentLoop(), 1); - QCOMPARE(sequence->currentAnimation(), a2_s_o1); - - // Current time = 251 - group.setCurrentTime(251); - QCOMPARE(group.currentTime(), 251); - QCOMPARE(sequence->currentTime(), 251); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 1); - QCOMPARE(a2_s_o1->currentLoop(), 0); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(sequence2->currentTime(), 251); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(a1_s_o3->currentTime(), 1); - QCOMPARE(a1_p_o1->currentTime(), 250); - QCOMPARE(a1_p_o2->currentTime(), 1); - QCOMPARE(a1_p_o2->currentLoop(), 1); - QCOMPARE(a1_p_o3->currentTime(), 250); - QCOMPARE(notTimeDriven->currentTime(), 251); - QCOMPARE(loopsForever->currentTime(), 1); - QCOMPARE(sequence->currentAnimation(), a2_s_o1); -} - -void tst_QAnimationGroup::statesAndSignals() -{ -} - -void tst_QAnimationGroup::setParentAutoAdd() -{ - QParallelAnimationGroup group; - QVariantAnimation *animation = new QPropertyAnimation(&group); - QCOMPARE(animation->group(), &group); -} - -void tst_QAnimationGroup::beginNestedGroup() -{ - QAnimationGroup *subGroup; - QAnimationGroup *parent = new QParallelAnimationGroup(); - - for (int i = 0; i < 10; ++i) { - if (i & 1) - subGroup = new QParallelAnimationGroup(parent); - else - subGroup = new QSequentialAnimationGroup(parent); - - QCOMPARE(parent->animationCount(), 1); - QAnimationGroup *child = static_cast(parent->animationAt(0)); - - QCOMPARE(child->parent(), static_cast(parent)); - if (i & 1) - QVERIFY(qobject_cast (child)); - else - QVERIFY(qobject_cast (child)); - - parent = child; - } -} - -void tst_QAnimationGroup::addChildTwice() -{ - QPropertyAnimation *subGroup; - QPropertyAnimation *subGroup2; - QAnimationGroup *parent = new QSequentialAnimationGroup(); - - subGroup = new QPropertyAnimation(); - subGroup->setParent(parent); - parent->addAnimation(subGroup); - QCOMPARE(parent->animationCount(), 1); - - parent->clearAnimations(); - - QCOMPARE(parent->animationCount(), 0); - - // adding the same item twice to a group will remove the item from its current position - // and append it to the end - subGroup = new QPropertyAnimation(parent); - subGroup2 = new QPropertyAnimation(parent); - - QCOMPARE(parent->animationCount(), 2); - QCOMPARE(parent->animationAt(0), subGroup); - QCOMPARE(parent->animationAt(1), subGroup2); - - parent->addAnimation(subGroup); - - QCOMPARE(parent->animationCount(), 2); - QCOMPARE(parent->animationAt(0), subGroup2); - QCOMPARE(parent->animationAt(1), subGroup); - - delete parent; -} - -void tst_QAnimationGroup::loopWithoutStartValue() -{ - QAnimationGroup *parent = new QSequentialAnimationGroup(); - QObject o; - o.setProperty("ole", 0); - QCOMPARE(o.property("ole").toInt(), 0); - - QPropertyAnimation anim1(&o, "ole"); - anim1.setEndValue(-50); - anim1.setDuration(100); - - QPropertyAnimation anim2(&o, "ole"); - anim2.setEndValue(50); - anim2.setDuration(100); - - parent->addAnimation(&anim1); - parent->addAnimation(&anim2); - - parent->setLoopCount(-1); - parent->start(); - - QVERIFY(anim1.startValue().isNull()); - QCOMPARE(anim1.currentValue().toInt(), 0); - QCOMPARE(parent->currentLoop(), 0); - - parent->setCurrentTime(200); - QCOMPARE(parent->currentLoop(), 1); - QCOMPARE(anim1.currentValue().toInt(), 50); - parent->stop(); -} - -QTEST_MAIN(tst_QAnimationGroup) -#include "tst_qanimationgroup.moc" diff --git a/tests/auto/qeasingcurve/qeasingcurve.pro b/tests/auto/qeasingcurve/qeasingcurve.pro deleted file mode 100644 index 2b66081..0000000 --- a/tests/auto/qeasingcurve/qeasingcurve.pro +++ /dev/null @@ -1,3 +0,0 @@ -load(qttest_p4) -QT = core -SOURCES += tst_qeasingcurve.cpp diff --git a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp deleted file mode 100644 index 8d42e5e..0000000 --- a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include - -#if QT_VERSION < 0x040200 -QTEST_NOOP_MAIN -#else - -#include - -//TESTED_CLASS= -//TESTED_FILES= - -class tst_QEasingCurve : public QObject { - Q_OBJECT - -public: - tst_QEasingCurve(); - virtual ~tst_QEasingCurve(); - -public Q_SLOTS: - void init(); - void cleanup(); - -private slots: - void type(); - void propertyDefaults(); - void valueForProgress_data(); - void valueForProgress(); - void setCustomType(); - void operators(); - -protected: -}; - -tst_QEasingCurve::tst_QEasingCurve() -{ -} - -tst_QEasingCurve::~tst_QEasingCurve() -{ -} - -void tst_QEasingCurve::init() -{ -} - -void tst_QEasingCurve::cleanup() -{ -} -#include - -void tst_QEasingCurve::type() -{ - { - QEasingCurve curve(QEasingCurve::Linear); - QCOMPARE(curve.period(), 0.3); - QCOMPARE(curve.amplitude(), 1.0); - - curve.setPeriod(5); - curve.setAmplitude(3); - QCOMPARE(curve.period(), 5.0); - QCOMPARE(curve.amplitude(), 3.0); - - curve.setType(QEasingCurve::InElastic); - QCOMPARE(curve.period(), 5.0); - QCOMPARE(curve.amplitude(), 3.0); - } - - { - QEasingCurve curve(QEasingCurve::InElastic); - QCOMPARE(curve.period(), 0.3); - QCOMPARE(curve.amplitude(), 1.0); - curve.setAmplitude(2); - QCOMPARE(curve.type(), QEasingCurve::InElastic); - curve.setType(QEasingCurve::Linear); - } - - { - // check bounaries - QEasingCurve curve(QEasingCurve::InCubic); - QTest::ignoreMessage(QtWarningMsg, "QEasingCurve: Invalid curve type 9999"); - curve.setType((QEasingCurve::Type)9999); - QCOMPARE(curve.type(), QEasingCurve::InCubic); - QTest::ignoreMessage(QtWarningMsg, "QEasingCurve: Invalid curve type -9999"); - curve.setType((QEasingCurve::Type)-9999); - QCOMPARE(curve.type(), QEasingCurve::InCubic); - QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QEasingCurve: Invalid curve type %1") - .arg(QEasingCurve::NCurveTypes).toLatin1().constData()); - curve.setType(QEasingCurve::NCurveTypes); - QCOMPARE(curve.type(), QEasingCurve::InCubic); - QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QEasingCurve: Invalid curve type %1") - .arg(QEasingCurve::Custom).toLatin1().constData()); - curve.setType(QEasingCurve::Custom); - QCOMPARE(curve.type(), QEasingCurve::InCubic); - QTest::ignoreMessage(QtWarningMsg, QString::fromAscii("QEasingCurve: Invalid curve type %1") - .arg(-1).toLatin1().constData()); - curve.setType((QEasingCurve::Type)-1); - QCOMPARE(curve.type(), QEasingCurve::InCubic); - curve.setType(QEasingCurve::Linear); - QCOMPARE(curve.type(), QEasingCurve::Linear); - curve.setType(QEasingCurve::CosineCurve); - QCOMPARE(curve.type(), QEasingCurve::CosineCurve); - } -} - -void tst_QEasingCurve::propertyDefaults() -{ - { - // checks if the defaults are correct, but also demonstrates a weakness with the API. - QEasingCurve curve(QEasingCurve::InElastic); - QCOMPARE(curve.period(), 0.3); - QCOMPARE(curve.amplitude(), 1.0); - QCOMPARE(curve.overshoot(), qreal(1.70158f)); - curve.setType(QEasingCurve::InBounce); - QCOMPARE(curve.period(), 0.3); - QCOMPARE(curve.amplitude(), 1.0); - QCOMPARE(curve.overshoot(), qreal(1.70158f)); - curve.setType(QEasingCurve::Linear); - QCOMPARE(curve.period(), 0.3); - QCOMPARE(curve.amplitude(), 1.0); - QCOMPARE(curve.overshoot(), qreal(1.70158f)); - curve.setType(QEasingCurve::InElastic); - QCOMPARE(curve.period(), 0.3); - QCOMPARE(curve.amplitude(), 1.0); - QCOMPARE(curve.overshoot(), qreal(1.70158f)); - curve.setPeriod(0.4); - curve.setAmplitude(0.6); - curve.setOvershoot(1.0); - curve.setType(QEasingCurve::Linear); - QCOMPARE(curve.period(), 0.4); - QCOMPARE(curve.amplitude(), 0.6); - QCOMPARE(curve.overshoot(), 1.0); - curve.setType(QEasingCurve::InElastic); - QCOMPARE(curve.period(), 0.4); - QCOMPARE(curve.amplitude(), 0.6); - QCOMPARE(curve.overshoot(), 1.0); - } -} - -typedef QList IntList; -Q_DECLARE_METATYPE(IntList) - -void tst_QEasingCurve::valueForProgress_data() -{ - QTest::addColumn("type"); - QTest::addColumn("at"); - QTest::addColumn("expected"); - // automatically generated. - // note that values are scaled from range [0,1] to range [0, 100] in order to store them as - // integer values and avoid fp inaccuracies - - QTest::newRow("Linear") << int(QEasingCurve::Linear) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100); - - QTest::newRow("InQuad") << int(QEasingCurve::InQuad) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 1 << 4 << 9 << 16 << 25 << 36 << 48 << 64 << 81 << 100); - - QTest::newRow("OutQuad") << int(QEasingCurve::OutQuad) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 19 << 36 << 51 << 64 << 75 << 84 << 90 << 96 << 99 << 100); - - QTest::newRow("InOutQuad") << int(QEasingCurve::InOutQuad) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 2 << 8 << 18 << 32 << 50 << 68 << 82 << 92 << 98 << 100); - - QTest::newRow("OutInQuad") << int(QEasingCurve::OutInQuad) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 18 << 32 << 42 << 48 << 50 << 52 << 57 << 68 << 82 << 100); - - QTest::newRow("InCubic") << int(QEasingCurve::InCubic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 2 << 6 << 12 << 21 << 34 << 51 << 72 << 100); - - QTest::newRow("OutCubic") << int(QEasingCurve::OutCubic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 27 << 48 << 65 << 78 << 87 << 93 << 97 << 99 << 99 << 100); - - QTest::newRow("InOutCubic") << int(QEasingCurve::InOutCubic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 3 << 10 << 25 << 50 << 74 << 89 << 96 << 99 << 100); - - QTest::newRow("OutInCubic") << int(QEasingCurve::OutInCubic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 24 << 39 << 46 << 49 << 50 << 50 << 53 << 60 << 75 << 100); - - QTest::newRow("InQuart") << int(QEasingCurve::InQuart) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 0 << 2 << 6 << 12 << 24 << 40 << 65 << 100); - - QTest::newRow("OutQuart") << int(QEasingCurve::OutQuart) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 34 << 59 << 75 << 87 << 93 << 97 << 99 << 99 << 99 << 100); - - QTest::newRow("InOutQuart") << int(QEasingCurve::InOutQuart) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 1 << 6 << 20 << 50 << 79 << 93 << 98 << 99 << 100); - - QTest::newRow("OutInQuart") << int(QEasingCurve::OutInQuart) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 29 << 43 << 48 << 49 << 50 << 50 << 51 << 56 << 70 << 100); - - QTest::newRow("InQuint") << int(QEasingCurve::InQuint) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 0 << 1 << 3 << 7 << 16 << 32 << 59 << 100); - - QTest::newRow("OutQuint") << int(QEasingCurve::OutQuint) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 40 << 67 << 83 << 92 << 96 << 98 << 99 << 99 << 99 << 100); - - QTest::newRow("InOutQuint") << int(QEasingCurve::InOutQuint) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 3 << 16 << 50 << 83 << 96 << 99 << 99 << 100); - - QTest::newRow("OutInQuint") << int(QEasingCurve::OutInQuint) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 33 << 46 << 49 << 49 << 50 << 50 << 50 << 53 << 66 << 100); - - QTest::newRow("InSine") << int(QEasingCurve::InSine) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 1 << 4 << 10 << 19 << 29 << 41 << 54 << 69 << 84 << 100); - - QTest::newRow("OutSine") << int(QEasingCurve::OutSine) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 15 << 30 << 45 << 58 << 70 << 80 << 89 << 95 << 98 << 100); - - QTest::newRow("InOutSine") << int(QEasingCurve::InOutSine) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 2 << 9 << 20 << 34 << 49 << 65 << 79 << 90 << 97 << 100); - - QTest::newRow("OutInSine") << int(QEasingCurve::OutInSine) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 15 << 29 << 40 << 47 << 50 << 52 << 59 << 70 << 84 << 100); - - QTest::newRow("InExpo") << int(QEasingCurve::InExpo) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 0 << 1 << 3 << 6 << 12 << 24 << 49 << 100); - - QTest::newRow("OutExpo") << int(QEasingCurve::OutExpo) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 50 << 75 << 87 << 93 << 96 << 98 << 99 << 99 << 99 << 100); - - QTest::newRow("InOutExpo") << int(QEasingCurve::InOutExpo) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 3 << 12 << 50 << 87 << 96 << 99 << 99 << 100); - - QTest::newRow("OutInExpo") << int(QEasingCurve::OutInExpo) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 37 << 46 << 49 << 49 << 50 << 50 << 50 << 53 << 62 << 100); - - QTest::newRow("InCirc") << int(QEasingCurve::InCirc) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 2 << 4 << 8 << 13 << 19 << 28 << 40 << 56 << 100); - - QTest::newRow("OutCirc") << int(QEasingCurve::OutCirc) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 43 << 59 << 71 << 80 << 86 << 91 << 95 << 97 << 99 << 100); - - QTest::newRow("InOutCirc") << int(QEasingCurve::InOutCirc) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 1 << 4 << 9 << 20 << 50 << 80 << 89 << 95 << 98 << 100); - - QTest::newRow("OutInCirc") << int(QEasingCurve::OutInCirc) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 29 << 40 << 45 << 48 << 50 << 51 << 54 << 60 << 70 << 100); - - QTest::newRow("InElastic") << int(QEasingCurve::InElastic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 0 << 1 << -1 << -3 << 12 << -12 << -25 << 100); - - QTest::newRow("OutElastic") << int(QEasingCurve::OutElastic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 125 << 112 << 87 << 103 << 101 << 98 << 100 << 100 << 99 << 100); - - QTest::newRow("InOutElastic") << int(QEasingCurve::InOutElastic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << -1 << -6 << 50 << 106 << 101 << 99 << 100 << 100); - - QTest::newRow("OutInElastic") << int(QEasingCurve::OutInElastic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 37 << 56 << 49 << 49 << 50 << 49 << 50 << 53 << 24 << 100); - - QTest::newRow("InBack") << int(QEasingCurve::InBack) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << -1 << -4 << -8 << -9 << -8 << -2 << 9 << 29 << 59 << 100); - - QTest::newRow("OutBack") << int(QEasingCurve::OutBack) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 40 << 70 << 90 << 102 << 108 << 109 << 108 << 104 << 101 << 100); - - QTest::newRow("InOutBack") << int(QEasingCurve::InOutBack) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << -3 << -9 << -7 << 8 << 50 << 91 << 107 << 109 << 103 << 100); - - QTest::newRow("OutInBack") << int(QEasingCurve::OutInBack) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 35 << 51 << 54 << 52 << 50 << 47 << 45 << 48 << 64 << 100); - - QTest::newRow("InBounce") << int(QEasingCurve::InBounce) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 1 << 6 << 6 << 22 << 23 << 9 << 31 << 69 << 92 << 100); - - QTest::newRow("OutBounce") << int(QEasingCurve::OutBounce) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 7 << 30 << 68 << 90 << 76 << 77 << 93 << 94 << 98 << 100); - - QTest::newRow("InOutBounce") << int(QEasingCurve::InOutBounce) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 3 << 11 << 4 << 34 << 50 << 65 << 95 << 88 << 97 << 100); - - QTest::newRow("OutInBounce") << int(QEasingCurve::OutInBounce) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 15 << 40 << 27 << 43 << 50 << 56 << 72 << 58 << 84 << 100); - - QTest::newRow("InCurve") << int(QEasingCurve::InCurve) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 2 << 10 << 23 << 37 << 50 << 60 << 70 << 80 << 90 << 100); - - QTest::newRow("OutCurve") << int(QEasingCurve::OutCurve) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 10 << 20 << 30 << 39 << 50 << 62 << 76 << 89 << 97 << 100); - - QTest::newRow("SineCurve") << int(QEasingCurve::SineCurve) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 9 << 34 << 65 << 90 << 100 << 90 << 65 << 34 << 9 << 0); - - QTest::newRow("CosineCurve") << int(QEasingCurve::CosineCurve) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 50 << 79 << 97 << 97 << 79 << 50 << 20 << 2 << 2 << 20 << 49); - -} - - -void tst_QEasingCurve::valueForProgress() -{ -#if 0 - // used to generate data tables... - QFile out; - out.open(stdout, QIODevice::WriteOnly); - for (int c = QEasingCurve::Linear; c < QEasingCurve::NCurveTypes - 1; ++c) { - QEasingCurve curve((QEasingCurve::Type)c); - QMetaObject mo = QEasingCurve::staticMetaObject; - QString strCurve = QLatin1String(mo.enumerator(mo.indexOfEnumerator("Type")).key(c)); - QString strInputs; - QString strOutputs; - - for (int t = 0; t <= 100; t+= 10) { - qreal ease = curve.valueForProgress(t/qreal(100)); - strInputs += QString::fromAscii(" << %1").arg(t); - strOutputs += QString::fromAscii(" << %1").arg(int(100*ease)); - - } - QString str = QString::fromAscii(" QTest::newRow(\"%1\") << int(QEasingCurve::%2)\n" - "\t\t << (IntList() %3)\n" - "\t\t << (IntList() %4);\n\n") - .arg(strCurve) - .arg(strCurve) - .arg(strInputs) - .arg(strOutputs); - out.write(str.toLatin1().constData()); - } - out.close(); - exit(1); -#else - QFETCH(int, type); - QFETCH(IntList, at); - QFETCH(IntList, expected); - - QEasingCurve curve((QEasingCurve::Type)type); - for (int i = 0; i < at.count(); ++i) { - qreal ease = curve.valueForProgress(at.at(i)/qreal(100)); - int ex = expected.at(i); - QCOMPARE(int(100*ease), ex); - } -#endif -} - -static qreal discreteEase(qreal progress) -{ - return qFloor(progress * 10) / qreal(10.0); -} - -void tst_QEasingCurve::setCustomType() -{ - QEasingCurve curve; - curve.setCustomType(&discreteEase); - QCOMPARE(curve.type(), QEasingCurve::Custom); - QCOMPARE(curve.valueForProgress(0.0), 0.0); - QCOMPARE(curve.valueForProgress(0.05), 0.0); - QCOMPARE(curve.valueForProgress(0.10), 0.1); - QCOMPARE(curve.valueForProgress(0.15), 0.1); - QCOMPARE(curve.valueForProgress(0.20), 0.2); - QCOMPARE(curve.valueForProgress(0.25), 0.2); - QCOMPARE(curve.valueForProgress(0.30), 0.3); - QCOMPARE(curve.valueForProgress(0.35), 0.3); - QCOMPARE(curve.valueForProgress(0.999999), 0.9); - - curve.setType(QEasingCurve::Linear); - QCOMPARE(curve.type(), QEasingCurve::Linear); - QCOMPARE(curve.valueForProgress(0.0), 0.0); - QCOMPARE(curve.valueForProgress(0.1), 0.1); - QCOMPARE(curve.valueForProgress(0.5), 0.5); - QCOMPARE(curve.valueForProgress(0.99), 0.99); -} - -void tst_QEasingCurve::operators() -{ - // operator= - QEasingCurve curve; - QEasingCurve curve2; - curve.setCustomType(&discreteEase); - curve2 = curve; - QCOMPARE(curve2.type(), QEasingCurve::Custom); - QCOMPARE(curve2.valueForProgress(0.0), 0.0); - QCOMPARE(curve2.valueForProgress(0.05), 0.0); - QCOMPARE(curve2.valueForProgress(0.15), 0.1); - QCOMPARE(curve2.valueForProgress(0.25), 0.2); - QCOMPARE(curve2.valueForProgress(0.35), 0.3); - QCOMPARE(curve2.valueForProgress(0.999999), 0.9); - - // operator== - curve.setType(QEasingCurve::InBack); - curve2 = curve; - curve2.setOvershoot(qreal(1.70158f)); - QCOMPARE(curve.overshoot(), curve2.overshoot()); - QVERIFY(curve2 == curve); - - curve.setOvershoot(3.0); - QVERIFY(curve2 != curve); - curve2.setOvershoot(3.0); - QVERIFY(curve2 == curve); - - curve2.setType(QEasingCurve::Linear); - QCOMPARE(curve.overshoot(), curve2.overshoot()); - QVERIFY(curve2 != curve); - curve2.setType(QEasingCurve::InBack); - QCOMPARE(curve.overshoot(), curve2.overshoot()); - QVERIFY(curve2 == curve); -} - - -QTEST_MAIN(tst_QEasingCurve) -#include "tst_qeasingcurve.moc" - -#endif //QT_VERSION diff --git a/tests/auto/qmake/testdata/bundle-spaces/some-file b/tests/auto/qmake/testdata/bundle-spaces/some-file index 9975dba..e69de29 100644 --- a/tests/auto/qmake/testdata/bundle-spaces/some-file +++ b/tests/auto/qmake/testdata/bundle-spaces/some-file @@ -1,6 +0,0 @@ -all: - C:\git\qt-kinetic-animations\bin\qmake qdir.pro -o Makefile -spec win32-msvc2008 - nmake -f Makefile -first: all -qmake: - C:\git\qt-kinetic-animations\bin\qmake qdir.pro -o Makefile -spec win32-msvc2008 diff --git a/tests/auto/qparallelanimationgroup/qparallelanimationgroup.pro b/tests/auto/qparallelanimationgroup/qparallelanimationgroup.pro deleted file mode 100644 index f2cacd3..0000000 --- a/tests/auto/qparallelanimationgroup/qparallelanimationgroup.pro +++ /dev/null @@ -1,5 +0,0 @@ -load(qttest_p4) -QT = core gui -SOURCES += tst_qparallelanimationgroup.cpp - - diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp deleted file mode 100644 index f2ab57a..0000000 --- a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp +++ /dev/null @@ -1,834 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include - -//TESTED_CLASS=QParallelAnimationGroup -//TESTED_FILES= - -Q_DECLARE_METATYPE(QAbstractAnimation::State) - -class tst_QParallelAnimationGroup : public QObject -{ - Q_OBJECT -public: - tst_QParallelAnimationGroup(); - virtual ~tst_QParallelAnimationGroup(); - -public Q_SLOTS: - void init(); - void cleanup(); - -private slots: - void construction(); - void setCurrentTime(); - void clearGroup(); - void propagateGroupUpdateToChildren(); - void updateChildrenWithRunningGroup(); - void deleteChildrenWithRunningGroup(); - void startChildrenWithStoppedGroup(); - void stopGroupWithRunningChild(); - void startGroupWithRunningChild(); - void zeroDurationAnimation(); - void stopUncontrolledAnimations(); - void loopCount_data(); - void loopCount(); - void autoAdd(); -}; - -tst_QParallelAnimationGroup::tst_QParallelAnimationGroup() -{ -} - -tst_QParallelAnimationGroup::~tst_QParallelAnimationGroup() -{ -} - -void tst_QParallelAnimationGroup::init() -{ - qRegisterMetaType("QAbstractAnimation::State"); -} - -void tst_QParallelAnimationGroup::cleanup() -{ -} - -void tst_QParallelAnimationGroup::construction() -{ - QParallelAnimationGroup animationgroup; -} - -class AnimationObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(int value READ value WRITE setValue) -public: - AnimationObject(int startValue = 0) - : v(startValue) - { } - - int value() const { return v; } - void setValue(int value) { v = value; } - - int v; -}; - -class TestAnimation : public QVariantAnimation -{ - Q_OBJECT -public: - virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)}; - virtual void updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) - { - Q_UNUSED(oldState) - Q_UNUSED(newState) - }; -}; - -class TestAnimation2 : public QVariantAnimation -{ - Q_OBJECT -public: - TestAnimation2(QAbstractAnimation *animation) : QVariantAnimation(animation) {} - TestAnimation2(int duration, QAbstractAnimation *animation) : QVariantAnimation(animation), m_duration(duration) {} - - virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)}; - virtual void updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) - { - Q_UNUSED(oldState) - Q_UNUSED(newState) - }; - - virtual int duration() const { - return m_duration; - } -private: - int m_duration; -}; - -class UncontrolledAnimation : public QPropertyAnimation -{ - Q_OBJECT -public: - UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0) - : QPropertyAnimation(target, propertyName, parent), id(0) - { - setDuration(250); - } - - int duration() const { return -1; /* not time driven */ } - -protected: - void timerEvent(QTimerEvent *event) - { - if (event->timerId() == id) - stop(); - } - - void updateRunning(bool running) - { - if (running) { - id = startTimer(500); - } else { - killTimer(id); - id = 0; - } - } - -private: - int id; -}; - -void tst_QParallelAnimationGroup::setCurrentTime() -{ - AnimationObject p_o1; - AnimationObject p_o2; - AnimationObject p_o3; - AnimationObject t_o1; - AnimationObject t_o2; - - // parallel operating on different object/properties - QAnimationGroup *parallel = new QParallelAnimationGroup(); - QVariantAnimation *a1_p_o1 = new QPropertyAnimation(&p_o1, "value"); - QVariantAnimation *a1_p_o2 = new QPropertyAnimation(&p_o2, "value"); - QVariantAnimation *a1_p_o3 = new QPropertyAnimation(&p_o3, "value"); - a1_p_o2->setLoopCount(3); - parallel->addAnimation(a1_p_o1); - parallel->addAnimation(a1_p_o2); - parallel->addAnimation(a1_p_o3); - - UncontrolledAnimation *notTimeDriven = new UncontrolledAnimation(&t_o1, "value"); - QCOMPARE(notTimeDriven->totalDuration(), -1); - - QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value"); - loopsForever->setLoopCount(-1); - QCOMPARE(loopsForever->totalDuration(), -1); - - QParallelAnimationGroup group; - group.addAnimation(parallel); - group.addAnimation(notTimeDriven); - group.addAnimation(loopsForever); - - // Current time = 1 - group.setCurrentTime(1); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(parallel->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_p_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_p_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_p_o3->state(), QAnimationGroup::Stopped); - QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); - QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); - - QCOMPARE(group.currentTime(), 1); - QCOMPARE(a1_p_o1->currentTime(), 1); - QCOMPARE(a1_p_o2->currentTime(), 1); - QCOMPARE(a1_p_o3->currentTime(), 1); - QCOMPARE(notTimeDriven->currentTime(), 1); - QCOMPARE(loopsForever->currentTime(), 1); - - // Current time = 250 - group.setCurrentTime(250); - QCOMPARE(group.currentTime(), 250); - QCOMPARE(a1_p_o1->currentTime(), 250); - QCOMPARE(a1_p_o2->currentTime(), 0); - QCOMPARE(a1_p_o2->currentLoop(), 1); - QCOMPARE(a1_p_o3->currentTime(), 250); - QCOMPARE(notTimeDriven->currentTime(), 250); - QCOMPARE(loopsForever->currentTime(), 0); - QCOMPARE(loopsForever->currentLoop(), 1); - - // Current time = 251 - group.setCurrentTime(251); - QCOMPARE(group.currentTime(), 251); - QCOMPARE(a1_p_o1->currentTime(), 250); - QCOMPARE(a1_p_o2->currentTime(), 1); - QCOMPARE(a1_p_o2->currentLoop(), 1); - QCOMPARE(a1_p_o3->currentTime(), 250); - QCOMPARE(notTimeDriven->currentTime(), 251); - QCOMPARE(loopsForever->currentTime(), 1); -} - -void tst_QParallelAnimationGroup::clearGroup() -{ - QParallelAnimationGroup group; - - for (int i = 0; i < 10; ++i) { - new QParallelAnimationGroup(&group); - } - - QCOMPARE(group.animationCount(), 10); - - int count = group.animationCount(); - QPointer *children = new QPointer[count]; - for (int i = 0; i < count; ++i) { - QVERIFY(group.animationAt(i) != 0); - children[i] = group.animationAt(i); - } - - group.clearAnimations(); - QCOMPARE(group.animationCount(), 0); - QCOMPARE(group.currentTime(), 0); - for (int i = 0; i < count; ++i) - QCOMPARE(children[i], QPointer()); - - delete[] children; -} - -void tst_QParallelAnimationGroup::propagateGroupUpdateToChildren() -{ - // this test verifies if group state changes are updating its children correctly - QParallelAnimationGroup group; - - QObject o; - o.setProperty("ole", 42); - QCOMPARE(o.property("ole").toInt(), 42); - - QPropertyAnimation anim1(&o, "ole"); - anim1.setEndValue(43); - anim1.setDuration(100); - QVERIFY(!anim1.currentValue().isValid()); - QCOMPARE(anim1.currentValue().toInt(), 0); - QCOMPARE(o.property("ole").toInt(), 42); - - TestAnimation anim2; - anim2.setStartValue(0); - anim2.setEndValue(100); - anim2.setDuration(200); - - QVERIFY(anim2.currentValue().isValid()); - QCOMPARE(anim2.currentValue().toInt(), 0); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - - group.start(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Running); - - group.pause(); - - QCOMPARE(group.state(), QAnimationGroup::Paused); - QCOMPARE(anim1.state(), QAnimationGroup::Paused); - QCOMPARE(anim2.state(), QAnimationGroup::Paused); - - group.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); -} - -void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup() -{ - // assert that its possible to modify a child's state directly while their group is running - QParallelAnimationGroup group; - - TestAnimation anim; - anim.setStartValue(0); - anim.setEndValue(100); - anim.setDuration(200); - - QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - QCOMPARE(groupStateChangedSpy.count(), 0); - QCOMPARE(childStateChangedSpy.count(), 0); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim.state(), QAnimationGroup::Stopped); - - group.addAnimation(&anim); - - group.start(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim.state(), QAnimationGroup::Running); - - QCOMPARE(groupStateChangedSpy.count(), 1); - QCOMPARE(childStateChangedSpy.count(), 1); - - QCOMPARE(qVariantValue(groupStateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(childStateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - - // starting directly a running child will not have any effect - anim.start(); - - QCOMPARE(groupStateChangedSpy.count(), 1); - QCOMPARE(childStateChangedSpy.count(), 1); - - anim.pause(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim.state(), QAnimationGroup::Paused); - - // in the animation stops directly, the group will still be running - anim.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim.state(), QAnimationGroup::Stopped); -} - -void tst_QParallelAnimationGroup::deleteChildrenWithRunningGroup() -{ - // test if children can be activated when their group is stopped - QParallelAnimationGroup group; - - QVariantAnimation *anim1 = new TestAnimation; - anim1->setStartValue(0); - anim1->setEndValue(100); - anim1->setDuration(200); - group.addAnimation(anim1); - - QCOMPARE(group.duration(), anim1->duration()); - - group.start(); - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim1->state(), QAnimationGroup::Running); - - QTest::qWait(50); - QVERIFY(group.currentTime() > 0); - - delete anim1; - QVERIFY(group.animationCount() == 0); - QCOMPARE(group.duration(), 0); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(group.currentTime(), 0); //that's the invariant -} - -void tst_QParallelAnimationGroup::startChildrenWithStoppedGroup() -{ - // test if children can be activated when their group is stopped - QParallelAnimationGroup group; - - TestAnimation anim1; - anim1.setStartValue(0); - anim1.setEndValue(100); - anim1.setDuration(200); - - TestAnimation anim2; - anim2.setStartValue(0); - anim2.setEndValue(100); - anim2.setDuration(200); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - - group.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - anim1.start(); - anim2.start(); - anim2.pause(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Paused); -} - -void tst_QParallelAnimationGroup::stopGroupWithRunningChild() -{ - // children that started independently will not be affected by a group stop - QParallelAnimationGroup group; - - TestAnimation anim1; - anim1.setStartValue(0); - anim1.setEndValue(100); - anim1.setDuration(200); - - TestAnimation anim2; - anim2.setStartValue(0); - anim2.setEndValue(100); - anim2.setDuration(200); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - - anim1.start(); - anim2.start(); - anim2.pause(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Paused); - - group.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Paused); - - anim1.stop(); - anim2.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); -} - -void tst_QParallelAnimationGroup::startGroupWithRunningChild() -{ - // as the group has precedence over its children, starting a group will restart all the children - QParallelAnimationGroup group; - - TestAnimation anim1; - anim1.setStartValue(0); - anim1.setEndValue(100); - anim1.setDuration(200); - - TestAnimation anim2; - anim2.setStartValue(0); - anim2.setEndValue(100); - anim2.setDuration(200); - - QSignalSpy stateChangedSpy1(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy stateChangedSpy2(&anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - QCOMPARE(stateChangedSpy1.count(), 0); - QCOMPARE(stateChangedSpy2.count(), 0); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - - anim1.start(); - anim2.start(); - anim2.pause(); - - QCOMPARE(qVariantValue(stateChangedSpy1.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(stateChangedSpy2.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(stateChangedSpy2.at(1).at(1)), - QAnimationGroup::Paused); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Paused); - - group.start(); - - QCOMPARE(stateChangedSpy1.count(), 3); - QCOMPARE(qVariantValue(stateChangedSpy1.at(1).at(1)), - QAnimationGroup::Stopped); - QCOMPARE(qVariantValue(stateChangedSpy1.at(2).at(1)), - QAnimationGroup::Running); - - QCOMPARE(stateChangedSpy2.count(), 4); - QCOMPARE(qVariantValue(stateChangedSpy2.at(2).at(1)), - QAnimationGroup::Stopped); - QCOMPARE(qVariantValue(stateChangedSpy2.at(3).at(1)), - QAnimationGroup::Running); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Running); -} - -void tst_QParallelAnimationGroup::zeroDurationAnimation() -{ - QParallelAnimationGroup group; - - TestAnimation anim1; - anim1.setStartValue(0); - anim1.setEndValue(100); - anim1.setDuration(0); - - TestAnimation anim2; - anim2.setStartValue(0); - anim2.setEndValue(100); - anim2.setDuration(100); - - QSignalSpy stateChangedSpy1(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy finishedSpy1(&anim1, SIGNAL(finished())); - - QSignalSpy stateChangedSpy2(&anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy finishedSpy2(&anim2, SIGNAL(finished())); - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - QCOMPARE(stateChangedSpy1.count(), 0); - group.start(); - QCOMPARE(stateChangedSpy1.count(), 2); - QCOMPARE(finishedSpy1.count(), 1); - QCOMPARE(qVariantValue(stateChangedSpy1.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(stateChangedSpy1.at(1).at(1)), - QAnimationGroup::Stopped); - - QCOMPARE(stateChangedSpy2.count(), 1); - QCOMPARE(finishedSpy2.count(), 0); - QCOMPARE(qVariantValue(stateChangedSpy1.at(0).at(1)), - QAnimationGroup::Running); - - - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Running); - QCOMPARE(group.state(), QAnimationGroup::Running); - - - group.stop(); - group.setLoopCount(4); - stateChangedSpy1.clear(); - stateChangedSpy2.clear(); - - group.start(); - QCOMPARE(stateChangedSpy1.count(), 2); - QCOMPARE(stateChangedSpy2.count(), 1); - group.setCurrentTime(50); - QCOMPARE(stateChangedSpy1.count(), 2); - QCOMPARE(stateChangedSpy2.count(), 1); - group.setCurrentTime(150); - QCOMPARE(stateChangedSpy1.count(), 4); - QCOMPARE(stateChangedSpy2.count(), 3); - group.setCurrentTime(50); - QCOMPARE(stateChangedSpy1.count(), 6); - QCOMPARE(stateChangedSpy2.count(), 5); - -} - -void tst_QParallelAnimationGroup::stopUncontrolledAnimations() -{ - QParallelAnimationGroup group; - - TestAnimation anim1; - anim1.setStartValue(0); - anim1.setEndValue(100); - anim1.setDuration(0); - - AnimationObject o1; - UncontrolledAnimation notTimeDriven(&o1, "value"); - QCOMPARE(notTimeDriven.totalDuration(), -1); - - TestAnimation loopsForever; - loopsForever.setStartValue(0); - loopsForever.setEndValue(100); - loopsForever.setDuration(100); - loopsForever.setLoopCount(-1); - - QSignalSpy stateChangedSpy(&anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - group.addAnimation(&anim1); - group.addAnimation(¬TimeDriven); - group.addAnimation(&loopsForever); - - group.start(); - - QCOMPARE(stateChangedSpy.count(), 2); - QCOMPARE(qVariantValue(stateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(stateChangedSpy.at(1).at(1)), - QAnimationGroup::Stopped); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running); - QCOMPARE(loopsForever.state(), QAnimationGroup::Running); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - - notTimeDriven.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); - QCOMPARE(loopsForever.state(), QAnimationGroup::Running); - - loopsForever.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); - QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped); -} - -struct AnimState { - AnimState(int time = -1) : time(time), state(-1) {} - AnimState(int time, int state) : time(time), state(state) {} - int time; - int state; -}; - -#define Running QAbstractAnimation::Running -#define Stopped QAbstractAnimation::Stopped - -Q_DECLARE_METATYPE(AnimState) -void tst_QParallelAnimationGroup::loopCount_data() -{ - QTest::addColumn("directionBackward"); - QTest::addColumn("setLoopCount"); - QTest::addColumn("initialGroupTime"); - QTest::addColumn("currentGroupTime"); - QTest::addColumn("expected1"); - QTest::addColumn("expected2"); - QTest::addColumn("expected3"); - - // D U R A T I O N - // 100 60*2 0 - // direction = Forward - QTest::newRow("50") << false << 3 << 0 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("100") << false << 3 << 0 << 100 << AnimState(100 ) << AnimState( 40, Running) << AnimState( 0, Stopped); - QTest::newRow("110") << false << 3 << 0 << 110 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("120") << false << 3 << 0 << 120 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped); - - QTest::newRow("170") << false << 3 << 0 << 170 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("220") << false << 3 << 0 << 220 << AnimState(100 ) << AnimState( 40, Running) << AnimState( 0, Stopped); - QTest::newRow("230") << false << 3 << 0 << 230 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("240") << false << 3 << 0 << 240 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped); - - QTest::newRow("290") << false << 3 << 0 << 290 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("340") << false << 3 << 0 << 340 << AnimState(100 ) << AnimState( 40, Running) << AnimState( 0, Stopped); - QTest::newRow("350") << false << 3 << 0 << 350 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("360") << false << 3 << 0 << 360 << AnimState(100, Stopped) << AnimState( 60 ) << AnimState( 0, Stopped); - - QTest::newRow("410") << false << 3 << 0 << 410 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped); - QTest::newRow("460") << false << 3 << 0 << 460 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped); - QTest::newRow("470") << false << 3 << 0 << 470 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped); - QTest::newRow("480") << false << 3 << 0 << 480 << AnimState(100, Stopped) << AnimState( 60, Stopped) << AnimState( 0, Stopped); - - // direction = Forward, rewind - QTest::newRow("120-110") << false << 3 << 120 << 110 << AnimState( 0, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("120-50") << false << 3 << 120 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("120-0") << false << 3 << 120 << 0 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped); - QTest::newRow("300-110") << false << 3 << 300 << 110 << AnimState( 0, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("300-50") << false << 3 << 300 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("300-0") << false << 3 << 300 << 0 << AnimState( 0, Running) << AnimState( 0, Running) << AnimState( 0, Stopped); - QTest::newRow("115-105") << false << 3 << 115 << 105 << AnimState( 42, Stopped) << AnimState( 45, Running) << AnimState( 0, Stopped); - - // direction = Backward - QTest::newRow("b120-120") << true << 3 << 120 << 120 << AnimState( 42, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); - QTest::newRow("b120-110") << true << 3 << 120 << 110 << AnimState( 42, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("b120-100") << true << 3 << 120 << 100 << AnimState(100, Running) << AnimState( 40, Running) << AnimState( 0, Stopped); - QTest::newRow("b120-50") << true << 3 << 120 << 50 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("b120-0") << true << 3 << 120 << 0 << AnimState( 0, Stopped) << AnimState( 0, Stopped) << AnimState( 0, Stopped); - QTest::newRow("b360-170") << true << 3 << 360 << 170 << AnimState( 50, Running) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("b360-220") << true << 3 << 360 << 220 << AnimState(100, Running) << AnimState( 40, Running) << AnimState( 0, Stopped); - QTest::newRow("b360-210") << true << 3 << 360 << 210 << AnimState( 90, Running) << AnimState( 30, Running) << AnimState( 0, Stopped); - QTest::newRow("b360-120") << true << 3 << 360 << 120 << AnimState( 0, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); - - // rewind, direction = Backward - QTest::newRow("b50-110") << true << 3 << 50 << 110 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - QTest::newRow("b50-120") << true << 3 << 50 << 120 << AnimState(100, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); - QTest::newRow("b50-140") << true << 3 << 50 << 140 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped); - QTest::newRow("b50-240") << true << 3 << 50 << 240 << AnimState(100, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); - QTest::newRow("b50-260") << true << 3 << 50 << 260 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped); - QTest::newRow("b50-350") << true << 3 << 50 << 350 << AnimState(100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - - // infinite looping - QTest::newRow("inf1220") << false << -1 << 0 << 1220 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped); - QTest::newRow("inf1310") << false << -1 << 0 << 1310 << AnimState( 100, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - // infinite looping, direction = Backward (will only loop once) - QTest::newRow("b.inf120-120") << true << -1 << 120 << 120 << AnimState( 42, Stopped) << AnimState( 60, Running) << AnimState( 0, Stopped); - QTest::newRow("b.inf120-20") << true << -1 << 120 << 20 << AnimState( 20, Running) << AnimState( 20, Running) << AnimState( 0, Stopped); - QTest::newRow("b.inf120-110") << true << -1 << 120 << 110 << AnimState( 42, Stopped) << AnimState( 50, Running) << AnimState( 0, Stopped); - - -} - -void tst_QParallelAnimationGroup::loopCount() -{ - QFETCH(bool, directionBackward); - QFETCH(int, setLoopCount); - QFETCH(int, initialGroupTime); - QFETCH(int, currentGroupTime); - QFETCH(AnimState, expected1); - QFETCH(AnimState, expected2); - QFETCH(AnimState, expected3); - - QParallelAnimationGroup group; - - TestAnimation anim1; - anim1.setStartValue(0); - anim1.setEndValue(100); - anim1.setDuration(100); - - TestAnimation anim2; - anim2.setStartValue(0); - anim2.setEndValue(100); - anim2.setDuration(60); //total 120 - anim2.setLoopCount(2); - - TestAnimation anim3; - anim3.setStartValue(0); - anim3.setEndValue(100); - anim3.setDuration(0); - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - group.addAnimation(&anim3); - - group.setLoopCount(setLoopCount); - if (initialGroupTime >= 0) - group.setCurrentTime(initialGroupTime); - if (directionBackward) - group.setDirection(QAbstractAnimation::Backward); - - group.start(); - if (initialGroupTime >= 0) - group.setCurrentTime(initialGroupTime); - - anim1.setCurrentTime(42); // 42 is "untouched" - anim2.setCurrentTime(42); - - group.setCurrentTime(currentGroupTime); - - QCOMPARE(anim1.currentTime(), expected1.time); - QCOMPARE(anim2.currentTime(), expected2.time); - QCOMPARE(anim3.currentTime(), expected3.time); - - if (expected1.state >=0) - QCOMPARE(int(anim1.state()), expected1.state); - if (expected2.state >=0) - QCOMPARE(int(anim2.state()), expected2.state); - if (expected3.state >=0) - QCOMPARE(int(anim3.state()), expected3.state); - -} - -void tst_QParallelAnimationGroup::autoAdd() -{ - QParallelAnimationGroup group; - QCOMPARE(group.duration(), 0); - TestAnimation2 *test = new TestAnimation2(250, &group); // 0, duration = 250; - QCOMPARE(test->group(), &group); - QCOMPARE(test->duration(), 250); - QCOMPARE(group.duration(), 250); - - test = new TestAnimation2(750, &group); // 1 - QCOMPARE(test->group(), &group); - QCOMPARE(group.duration(), 750); - test = new TestAnimation2(500, &group); // 2 - QCOMPARE(test->group(), &group); - QCOMPARE(group.duration(), 750); - - delete group.animationAt(1); // remove the one with duration = 750 - QCOMPARE(group.duration(), 500); - - delete group.animationAt(1); // remove the one with duration = 500 - QCOMPARE(group.duration(), 250); - - test = static_cast(group.animationAt(0)); - test->setParent(0); // remove the last one (with duration = 250) - QCOMPARE(test->group(), static_cast(0)); - QCOMPARE(group.duration(), 0); -} - -QTEST_MAIN(tst_QParallelAnimationGroup) -#include "tst_qparallelanimationgroup.moc" diff --git a/tests/auto/qpropertyanimation/qpropertyanimation.pro b/tests/auto/qpropertyanimation/qpropertyanimation.pro deleted file mode 100644 index 6d6ddbf..0000000 --- a/tests/auto/qpropertyanimation/qpropertyanimation.pro +++ /dev/null @@ -1,5 +0,0 @@ -load(qttest_p4) -QT = core gui -SOURCES += tst_qpropertyanimation.cpp - - diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp deleted file mode 100644 index 7e910d4..0000000 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ /dev/null @@ -1,919 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include -#include - -//TESTED_CLASS=QPropertyAnimation -//TESTED_FILES= - -class UncontrolledAnimation : public QPropertyAnimation -{ - Q_OBJECT -public: - int duration() const { return -1; /* not time driven */ } - -protected: - void updateCurrentTime(int msecs) - { - QPropertyAnimation::updateCurrentTime(msecs); - if (msecs >= QPropertyAnimation::duration()) - stop(); - } -}; - -class tst_QPropertyAnimation : public QObject -{ - Q_OBJECT -public: - tst_QPropertyAnimation(); - virtual ~tst_QPropertyAnimation(); - -public Q_SLOTS: - void init(); - void cleanup(); - -private slots: - void construction(); - void setCurrentTime_data(); - void setCurrentTime(); - void statesAndSignals_data(); - void statesAndSignals(); - void deletion1(); - void deletion2(); - void deletion3(); - void duration0(); - void noStartValue(); - void noStartValueWithLoop(); - void startWhenAnotherIsRunning(); - void easingcurve_data(); - void easingcurve(); - void startWithoutStartValue(); - void playForwardBackward(); - void interpolated(); - void setStartEndValues(); - void zeroDurationStart(); - void operationsInStates_data(); - void operationsInStates(); - void oneKeyValue(); - void updateOnSetKeyValues(); -}; - -tst_QPropertyAnimation::tst_QPropertyAnimation() -{ -} - -tst_QPropertyAnimation::~tst_QPropertyAnimation() -{ -} - -void tst_QPropertyAnimation::init() -{ - qRegisterMetaType("QAbstractAnimation::State"); - qRegisterMetaType("QAbstractAnimation::DeletionPolicy"); -} - -void tst_QPropertyAnimation::cleanup() -{ -} - -class AnimationObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(int value READ value WRITE setValue) - Q_PROPERTY(qreal realValue READ realValue WRITE setRealValue) -public: - AnimationObject(int startValue = 0) - : v(startValue) - { } - - int value() const { return v; } - void setValue(int value) { v = value; } - - qreal realValue() const { return rv; } - void setRealValue(qreal value) { rv = value; } - - int v; - qreal rv; -}; - - -void tst_QPropertyAnimation::construction() -{ - QPropertyAnimation panimation; -} - -void tst_QPropertyAnimation::setCurrentTime_data() -{ - QTest::addColumn("duration"); - QTest::addColumn("loopCount"); - QTest::addColumn("currentTime"); - QTest::addColumn("testCurrentTime"); - QTest::addColumn("testCurrentLoop"); - - QTest::newRow("-1") << -1 << 1 << 0 << 0 << 0; - QTest::newRow("0") << 0 << 1 << 0 << 0 << 0; - QTest::newRow("1") << 0 << 1 << 1 << 0 << 0; - QTest::newRow("2") << 0 << 2 << 1 << 0 << 0; - QTest::newRow("3") << 1 << 1 << 0 << 0 << 0; - QTest::newRow("4") << 1 << 1 << 1 << 1 << 0; - QTest::newRow("5") << 1 << 2 << 1 << 0 << 1; - QTest::newRow("6") << 1 << 2 << 2 << 1 << 1; - QTest::newRow("7") << 1 << 2 << 3 << 1 << 1; - QTest::newRow("8") << 1 << 3 << 2 << 0 << 2; - QTest::newRow("9") << 1 << 3 << 3 << 1 << 2; - QTest::newRow("a") << 10 << 1 << 0 << 0 << 0; - QTest::newRow("b") << 10 << 1 << 1 << 1 << 0; - QTest::newRow("c") << 10 << 1 << 10 << 10 << 0; - QTest::newRow("d") << 10 << 2 << 10 << 0 << 1; - QTest::newRow("e") << 10 << 2 << 11 << 1 << 1; - QTest::newRow("f") << 10 << 2 << 20 << 10 << 1; - QTest::newRow("g") << 10 << 2 << 21 << 10 << 1; - QTest::newRow("negloop 0") << 10 << -1 << 0 << 0 << 0; - QTest::newRow("negloop 1") << 10 << -1 << 10 << 0 << 1; - QTest::newRow("negloop 2") << 10 << -1 << 15 << 5 << 1; - QTest::newRow("negloop 3") << 10 << -1 << 20 << 0 << 2; - QTest::newRow("negloop 4") << 10 << -1 << 30 << 0 << 3; -} - -void tst_QPropertyAnimation::setCurrentTime() -{ - QFETCH(int, duration); - QFETCH(int, loopCount); - QFETCH(int, currentTime); - QFETCH(int, testCurrentTime); - QFETCH(int, testCurrentLoop); - - QPropertyAnimation animation; - if (duration < 0) - QTest::ignoreMessage(QtWarningMsg, "QVariantAnimation::setDuration: cannot set a negative duration"); - animation.setDuration(duration); - animation.setLoopCount(loopCount); - animation.setCurrentTime(currentTime); - - QCOMPARE(animation.currentTime(), testCurrentTime); - QCOMPARE(animation.currentLoop(), testCurrentLoop); -} - -void tst_QPropertyAnimation::statesAndSignals_data() -{ - QTest::addColumn("uncontrolled"); - QTest::newRow("normal animation") << false; - QTest::newRow("animation with undefined duration") << true; -} - -void tst_QPropertyAnimation::statesAndSignals() -{ - QFETCH(bool, uncontrolled); - QPropertyAnimation *anim = uncontrolled ? new UncontrolledAnimation : new QPropertyAnimation; - anim->setDuration(100); - - QSignalSpy finishedSpy(anim, SIGNAL(finished())); - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy currentLoopSpy(anim, SIGNAL(currentLoopChanged(int))); - - anim->setCurrentTime(1); - anim->setCurrentTime(100); - QCOMPARE(finishedSpy.count(), 0); - QCOMPARE(runningSpy.count(), 0); - QCOMPARE(currentLoopSpy.count(), 0); - QCOMPARE(anim->state(), QAnimationGroup::Stopped); - - anim->setLoopCount(3); - anim->setCurrentTime(101); - - if (uncontrolled) - QSKIP("Uncontrolled animations don't handle looping", SkipSingle); - - QCOMPARE(currentLoopSpy.count(), 1); - QCOMPARE(anim->currentLoop(), 1); - - anim->setCurrentTime(0); - QCOMPARE(currentLoopSpy.count(), 2); - QCOMPARE(anim->currentLoop(), 0); - - anim->start(); - QCOMPARE(anim->state(), QAnimationGroup::Running); - QCOMPARE(runningSpy.count(), 1); //anim must have started - QCOMPARE(anim->currentLoop(), 0); - runningSpy.clear(); - - anim->stop(); - QCOMPARE(anim->state(), QAnimationGroup::Stopped); - QCOMPARE(runningSpy.count(), 1); //anim must have stopped - QCOMPARE(finishedSpy.count(), 0); - QCOMPARE(anim->currentTime(), 0); - QCOMPARE(anim->currentLoop(), 0); - QCOMPARE(currentLoopSpy.count(), 2); - runningSpy.clear(); - - anim->start(); - QTest::qWait(1000); - QCOMPARE(anim->state(), QAnimationGroup::Stopped); - QCOMPARE(runningSpy.count(), 2); //started and stopped again - runningSpy.clear(); - QCOMPARE(finishedSpy.count(), 1); - QCOMPARE(anim->currentTime(), 100); - QCOMPARE(anim->currentLoop(), 2); - QCOMPARE(currentLoopSpy.count(), 4); - - anim->start(); // auto-rewinds - QCOMPARE(anim->state(), QAnimationGroup::Running); - QCOMPARE(anim->currentTime(), 0); - QCOMPARE(anim->currentLoop(), 0); - QCOMPARE(currentLoopSpy.count(), 5); - QCOMPARE(runningSpy.count(), 1); // anim has started - QCOMPARE(finishedSpy.count(), 1); - QCOMPARE(anim->currentLoop(), 0); - runningSpy.clear(); - - QTest::qWait(1000); - - QCOMPARE(currentLoopSpy.count(), 7); - QCOMPARE(anim->state(), QAnimationGroup::Stopped); - QCOMPARE(anim->currentLoop(), 2); - QCOMPARE(runningSpy.count(), 1); // anim has stopped - QCOMPARE(finishedSpy.count(), 2); - QCOMPARE(anim->currentTime(), 100); - - delete anim; -} - -void tst_QPropertyAnimation::deletion1() -{ - QObject *object = new QWidget; - QPointer anim = new QPropertyAnimation(object,"minimumWidth"); - - //test that the animation is deleted correctly depending of the deletion flag passed in start() - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy finishedSpy(anim, SIGNAL(finished())); - anim->setStartValue(10); - anim->setEndValue(20); - anim->setDuration(200); - anim->start(); - QCOMPARE(runningSpy.count(), 1); - QCOMPARE(finishedSpy.count(), 0); - - QVERIFY(anim); - QCOMPARE(anim->state(), QAnimationGroup::Running); - QTest::qWait(100); - QVERIFY(anim); - QCOMPARE(anim->state(), QAnimationGroup::Running); - QTest::qWait(150); - QVERIFY(anim); //The animation should not have been deleted - QCOMPARE(anim->state(), QAnimationGroup::Stopped); - QCOMPARE(runningSpy.count(), 2); - QCOMPARE(finishedSpy.count(), 1); - - anim->start(QVariantAnimation::DeleteWhenStopped); - QVERIFY(anim); - QCOMPARE(anim->state(), QAnimationGroup::Running); - QTest::qWait(100); - QVERIFY(anim); - QCOMPARE(anim->state(), QAnimationGroup::Running); - QTest::qWait(150); - QVERIFY(!anim); //The animation must have been deleted - QCOMPARE(runningSpy.count(), 4); - QCOMPARE(finishedSpy.count(), 2); - delete object; -} - -void tst_QPropertyAnimation::deletion2() -{ - //test that the animation get deleted if the object is deleted - QObject *object = new QWidget; - QPointer anim = new QPropertyAnimation(object,"minimumWidth"); - anim->setStartValue(10); - anim->setEndValue(20); - anim->setDuration(200); - - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy finishedSpy(anim, SIGNAL(finished())); - - anim->setStartValue(10); - anim->setEndValue(20); - anim->setDuration(200); - anim->start(); - - QTest::qWait(50); - QVERIFY(anim); - QCOMPARE(anim->state(), QAnimationGroup::Running); - - QCOMPARE(runningSpy.count(), 1); - QCOMPARE(finishedSpy.count(), 0); - - //we can't call deletaLater directly because the delete would only happen in the next loop of _this_ event loop - QTimer::singleShot(0, object, SLOT(deleteLater())); - QTest::qWait(50); - - QVERIFY(anim->targetObject() == 0); -} - -void tst_QPropertyAnimation::deletion3() -{ - //test that the stopped signal is emit when the animation is destroyed - QObject *object = new QWidget; - QPropertyAnimation *anim = new QPropertyAnimation(object,"minimumWidth"); - anim->setStartValue(10); - anim->setEndValue(20); - anim->setDuration(200); - - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy finishedSpy(anim, SIGNAL(finished())); - anim->start(); - - QTest::qWait(50); - QCOMPARE(anim->state(), QAnimationGroup::Running); - QCOMPARE(runningSpy.count(), 1); - QCOMPARE(finishedSpy.count(), 0); - delete anim; - QCOMPARE(runningSpy.count(), 2); - QCOMPARE(finishedSpy.count(), 0); -} - -void tst_QPropertyAnimation::duration0() -{ - QObject o; - o.setProperty("ole", 42); - QCOMPARE(o.property("ole").toInt(), 42); - - QPropertyAnimation animation(&o, "ole"); - animation.setEndValue(43); - QVERIFY(!animation.currentValue().isValid()); - QCOMPARE(animation.currentValue().toInt(), 0); - QCOMPARE(o.property("ole").toInt(), 42); - animation.setDuration(0); - animation.start(); - QCOMPARE(animation.state(), QAnimationGroup::Stopped); - QCOMPARE(animation.currentTime(), 0); - QCOMPARE(o.property("ole").toInt(), 43); -} - -class StartValueTester : public QObject -{ - Q_OBJECT - Q_PROPERTY(int ole READ ole WRITE setOle) -public: - StartValueTester() : o(0) { } - int ole() const { return o; } - void setOle(int v) { o = v; values << v; } - - int o; - QList values; -}; - -void tst_QPropertyAnimation::noStartValue() -{ - StartValueTester o; - o.setProperty("ole", 42); - o.values.clear(); - - QPropertyAnimation a(&o, "ole"); - a.setEndValue(420); - a.setDuration(250); - a.start(); - - QTest::qWait(300); - - QCOMPARE(o.values.first(), 42); - QCOMPARE(o.values.last(), 420); -} - -void tst_QPropertyAnimation::noStartValueWithLoop() -{ - StartValueTester o; - o.setProperty("ole", 42); - o.values.clear(); - - QPropertyAnimation a(&o, "ole"); - a.setEndValue(420); - a.setDuration(250); - a.setLoopCount(2); - a.start(); - - a.setCurrentTime(250); - QCOMPARE(o.values.first(), 42); - QCOMPARE(a.currentValue().toInt(), 42); - QCOMPARE(o.values.last(), 42); - - a.setCurrentTime(500); - QCOMPARE(a.currentValue().toInt(), 420); -} - -void tst_QPropertyAnimation::startWhenAnotherIsRunning() -{ - StartValueTester o; - o.setProperty("ole", 42); - o.values.clear(); - - { - //normal case: the animation finishes and is deleted - QPointer anim = new QPropertyAnimation(&o, "ole"); - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - anim->start(QVariantAnimation::DeleteWhenStopped); - QTest::qWait(anim->duration() + 50); - QCOMPARE(runningSpy.count(), 2); //started and then stopped - QVERIFY(!anim); - } - - { - QPointer anim = new QPropertyAnimation(&o, "ole"); - QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - anim->start(QVariantAnimation::DeleteWhenStopped); - QTest::qWait(anim->duration()/2); - QPointer anim2 = new QPropertyAnimation(&o, "ole"); - QCOMPARE(runningSpy.count(), 1); - QCOMPARE(anim->state(), QVariantAnimation::Running); - - //anim2 will interrupt anim1 - QMetaObject::invokeMethod(anim2, "start", Qt::QueuedConnection, Q_ARG(QAbstractAnimation::DeletionPolicy, QVariantAnimation::DeleteWhenStopped)); - QTest::qWait(50); - QVERIFY(!anim); //anim should have been deleted - QVERIFY(anim2); - QTest::qWait(anim2->duration()); - QVERIFY(!anim2); //anim2 is finished: it should have been deleted by now - QVERIFY(!anim); - } - -} - -// copy from easing.cpp in case that function changes definition -static qreal easeInOutBack(qreal t) -{ - qreal s = 1.70158; - qreal t_adj = 2.0f * (qreal)t; - if (t_adj < 1) { - s *= 1.525f; - return 1.0/2*(t_adj*t_adj*((s+1)*t_adj - s)); - } else { - t_adj -= 2; - s *= 1.525f; - return 1.0/2*(t_adj*t_adj*((s+1)*t_adj + s) + 2); - } -} - -void tst_QPropertyAnimation::easingcurve_data() -{ - QTest::addColumn("currentTime"); - QTest::addColumn("expectedvalue"); - - QTest::newRow("interpolation1") << 0 << 0; - QTest::newRow("interpolation2") << 1000 << 1000; - QTest::newRow("extrapolationbelow") << 250 << -99; - QTest::newRow("extrapolationabove") << 750 << 1099; -} - -void tst_QPropertyAnimation::easingcurve() -{ - QFETCH(int, currentTime); - QFETCH(int, expectedvalue); - QObject o; - o.setProperty("ole", 42); - QCOMPARE(o.property("ole").toInt(), 42); - - QPropertyAnimation pAnimation(&o, "ole"); - pAnimation.setStartValue(0); - pAnimation.setEndValue(1000); - pAnimation.setDuration(1000); - - // this easingcurve assumes that we extrapolate before startValue and after endValue - QEasingCurve easingCurve; - easingCurve.setCustomType(easeInOutBack); - pAnimation.setEasingCurve(easingCurve); - pAnimation.start(); - pAnimation.pause(); - pAnimation.setCurrentTime(currentTime); - QCOMPARE(o.property("ole").toInt(), expectedvalue); -} - -void tst_QPropertyAnimation::startWithoutStartValue() -{ - QObject o; - o.setProperty("ole", 42); - QCOMPARE(o.property("ole").toInt(), 42); - - QPropertyAnimation anim(&o, "ole"); - anim.setEndValue(100); - - anim.start(); - - QTest::qWait(100); - int current = anim.currentValue().toInt(); - //it is somewhere in the animation - QVERIFY(current > 42); - QVERIFY(current < 100); - - QTest::qWait(200); - QCOMPARE(anim.state(), QVariantAnimation::Stopped); - - anim.setEndValue(110); - anim.start(); - current = anim.currentValue().toInt(); - // the default start value will reevaluate the current property - // and set it to the end value of the last iteration - QCOMPARE(current, 100); - QTest::qWait(100); - current = anim.currentValue().toInt(); - //it is somewhere in the animation - QVERIFY(current >= 100); - QVERIFY(current <= 110); -} - -void tst_QPropertyAnimation::playForwardBackward() -{ - QObject o; - o.setProperty("ole", 0); - QCOMPARE(o.property("ole").toInt(), 0); - - QPropertyAnimation anim(&o, "ole"); - anim.setEndValue(100); - anim.start(); - QTest::qWait(anim.duration() + 50); - QCOMPARE(anim.state(), QAbstractAnimation::Stopped); - QCOMPARE(anim.currentTime(), anim.duration()); - - //the animation is at the end - anim.setDirection(QVariantAnimation::Backward); - anim.start(); - QCOMPARE(anim.state(), QAbstractAnimation::Running); - QTest::qWait(anim.duration() + 50); - QCOMPARE(anim.state(), QAbstractAnimation::Stopped); - QCOMPARE(anim.currentTime(), 0); - - //the direction is backward - //restarting should jump to the end - anim.start(); - QCOMPARE(anim.state(), QAbstractAnimation::Running); - QCOMPARE(anim.currentTime(), anim.duration()); - QTest::qWait(anim.duration() + 50); - QCOMPARE(anim.state(), QAbstractAnimation::Stopped); - QCOMPARE(anim.currentTime(), 0); -} - -struct Number -{ - Number() {} - Number(int n) - : n(n) {} - - Number(const Number &other) - : n(other.n){} - - Number &operator=(const Number &other) { - n = other.n; - return *this; - } - bool operator==(const Number &other) const { - return n == other.n; - } - - int n; -}; - -Q_DECLARE_METATYPE(Number) -Q_DECLARE_METATYPE(QAbstractAnimation::State) - -QVariant numberInterpolator(const Number &f, const Number &t, qreal progress) -{ - return qVariantFromValue(Number(f.n + (t.n - f.n)*progress)); -} - -QVariant xaxisQPointInterpolator(const QPointF &f, const QPointF &t, qreal progress) -{ - return QPointF(f.x() + (t.x() - f.x())*progress, f.y()); -} - -void tst_QPropertyAnimation::interpolated() -{ - QObject o; - o.setProperty("point", QPointF()); //this will avoid warnings - o.setProperty("number", qVariantFromValue(Number(42))); - QCOMPARE(qVariantValue(o.property("number")), Number(42)); - { - qRegisterAnimationInterpolator(numberInterpolator); - QPropertyAnimation anim(&o, "number"); - anim.setStartValue(qVariantFromValue(Number(0))); - anim.setEndValue(qVariantFromValue(Number(100))); - anim.setDuration(1000); - anim.start(); - anim.pause(); - anim.setCurrentTime(100); - Number t(qVariantValue(o.property("number"))); - QCOMPARE(t, Number(10)); - anim.setCurrentTime(500); - QCOMPARE(qVariantValue(o.property("number")), Number(50)); - } - { - qRegisterAnimationInterpolator(xaxisQPointInterpolator); - QPropertyAnimation anim(&o, "point"); - anim.setStartValue(QPointF(0,0)); - anim.setEndValue(QPointF(100, 100)); - anim.setDuration(1000); - anim.start(); - anim.pause(); - anim.setCurrentTime(100); - QCOMPARE(o.property("point"), QVariant(QPointF(10, 0))); - anim.setCurrentTime(500); - QCOMPARE(o.property("point"), QVariant(QPointF(50, 0))); - } - { - // unregister it and see if we get back the default behaviour - qRegisterAnimationInterpolator(0); - QPropertyAnimation anim(&o, "point"); - anim.setStartValue(QPointF(0,0)); - anim.setEndValue(QPointF(100, 100)); - anim.setDuration(1000); - anim.start(); - anim.pause(); - anim.setCurrentTime(100); - QCOMPARE(o.property("point").toPointF(), QPointF(10, 10)); - anim.setCurrentTime(500); - QCOMPARE(o.property("point").toPointF(), QPointF(50, 50)); - } - - { - // Interpolate a qreal property with a int interpolator - AnimationObject o1; - o1.setRealValue(42.42); - QPropertyAnimation anim(&o1, "realValue"); - anim.setStartValue(0); - anim.setEndValue(100); - anim.start(); - QCOMPARE(o1.realValue(), qreal(0)); - anim.setCurrentTime(250); - QCOMPARE(o1.realValue(), qreal(100)); - } -} - -void tst_QPropertyAnimation::setStartEndValues() -{ - //this tests the start value, end value and default start value - QObject o; - o.setProperty("ole", 42); - QPropertyAnimation anim(&o, "ole"); - QVariantAnimation::KeyValues values; - QCOMPARE(anim.keyValues(), values); - - //let's add a start value - anim.setStartValue(0); - values << QVariantAnimation::KeyValue(0, 0); - QCOMPARE(anim.keyValues(), values); - - anim.setEndValue(10); - values << QVariantAnimation::KeyValue(1, 10); - QCOMPARE(anim.keyValues(), values); - - //now we can play with objects - QCOMPARE(o.property("ole").toInt(), 42); - QCOMPARE(o.property("ole").toInt(), 42); - anim.start(); - QVERIFY(anim.startValue().isValid()); - QCOMPARE(o.property("ole"), anim.startValue()); - - //now we remove the explicit start value and test the implicit one - anim.stop(); - o.setProperty("ole", 42); - values.remove(0); - anim.setStartValue(QVariant()); //reset the start value - QCOMPARE(anim.keyValues(), values); - QVERIFY(!anim.startValue().isValid()); - anim.start(); - QCOMPARE(o.property("ole").toInt(), 42); - anim.setCurrentTime(anim.duration()/2); - QCOMPARE(o.property("ole").toInt(), 26); //just in the middle of the animation - anim.setCurrentTime(anim.duration()); - QCOMPARE(anim.state(), QAnimationGroup::Stopped); //it should have stopped - QVERIFY(anim.endValue().isValid()); - QCOMPARE(o.property("ole"), anim.endValue()); //end of the animations - - //now we set back the startValue - anim.setStartValue(5); - QVERIFY(anim.startValue().isValid()); - anim.start(); - QCOMPARE(o.property("ole").toInt(), 5); -} - -void tst_QPropertyAnimation::zeroDurationStart() -{ - QPropertyAnimation anim; - QSignalSpy spy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - anim.setDuration(0); - QCOMPARE(anim.state(), QAbstractAnimation::Stopped); - anim.start(); - //the animation stops immediately - QCOMPARE(anim.state(), QAbstractAnimation::Stopped); - QCOMPARE(spy.count(), 2); - - //let's check the first state change - const QVariantList firstChange = spy.first(); - //old state - QCOMPARE(qVariantValue(firstChange.first()), QAbstractAnimation::Stopped); - //new state - QCOMPARE(qVariantValue(firstChange.last()), QAbstractAnimation::Running); - - //let's check the first state change - const QVariantList secondChange = spy.last(); - //old state - QCOMPARE(qVariantValue(secondChange.first()), QAbstractAnimation::Running); - //new state - QCOMPARE(qVariantValue(secondChange.last()), QAbstractAnimation::Stopped); -} - -#define Pause 1 -#define Start 2 -#define Resume 3 -#define Stop 4 - -void tst_QPropertyAnimation::operationsInStates_data() -{ - QTest::addColumn("originState"); - QTest::addColumn("operation"); - QTest::addColumn("expectedWarning"); - QTest::addColumn("expectedState"); - - QString pauseWarn(QLatin1String("QAbstractAnimation::pause: Cannot pause a stopped animation")); - QString resumeWarn(QLatin1String("QAbstractAnimation::resume: Cannot resume an animation that is not paused")); - - QTest::newRow("S-pause") << QAbstractAnimation::Stopped << Pause << pauseWarn << QAbstractAnimation::Stopped; - QTest::newRow("S-start") << QAbstractAnimation::Stopped << Start << QString() << QAbstractAnimation::Running; - QTest::newRow("S-resume") << QAbstractAnimation::Stopped << Resume << resumeWarn << QAbstractAnimation::Stopped; - QTest::newRow("S-stop") << QAbstractAnimation::Stopped << Stop << QString() << QAbstractAnimation::Stopped; - - QTest::newRow("P-pause") << QAbstractAnimation::Paused << Pause << QString() << QAbstractAnimation::Paused; - QTest::newRow("P-start") << QAbstractAnimation::Paused << Start << QString() << QAbstractAnimation::Running; - QTest::newRow("P-resume") << QAbstractAnimation::Paused << Resume << QString() << QAbstractAnimation::Running; - QTest::newRow("P-stop") << QAbstractAnimation::Paused << Stop << QString() << QAbstractAnimation::Stopped; - - QTest::newRow("R-pause") << QAbstractAnimation::Running << Pause << QString() << QAbstractAnimation::Paused; - QTest::newRow("R-start") << QAbstractAnimation::Running << Start << QString() << QAbstractAnimation::Running; - QTest::newRow("R-resume") << QAbstractAnimation::Running << Resume << resumeWarn << QAbstractAnimation::Running; - QTest::newRow("R-stop") << QAbstractAnimation::Running << Stop << QString() << QAbstractAnimation::Stopped; -} - -void tst_QPropertyAnimation::operationsInStates() -{ -/** - * | pause() |start() |resume() |stop() - * ----------+------------+-----------+-----------+-------------------+ - * Stopped | Stopped |Running |Stopped |Stopped | - * _| qWarning |restart |qWarning | | - * Paused | Paused |Running |Running |Stopped | - * _| | | | | - * Running | Paused |Running |Running |Stopped | - * | |restart |qWarning | | - * ----------+------------+-----------+-----------+-------------------+ -**/ - - QFETCH(QAbstractAnimation::State, originState); - QFETCH(int, operation); - QFETCH(QString, expectedWarning); - QFETCH(QAbstractAnimation::State, expectedState); - - QObject o; - o.setProperty("ole", 42); - QPropertyAnimation anim(&o, "ole"); - QSignalSpy spy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - anim.stop(); - switch (originState) { - case QAbstractAnimation::Stopped: - break; - case QAbstractAnimation::Paused: - anim.start(); - anim.pause(); - break; - case QAbstractAnimation::Running: - anim.start(); - break; - } - if (!expectedWarning.isEmpty()) { - QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); - } - QCOMPARE(anim.state(), originState); - switch (operation) { - case Pause: - anim.pause(); - break; - case Start: - anim.start(); - break; - case Resume: - anim.resume(); - break; - case Stop: - anim.stop(); - break; - } - - QCOMPARE(anim.state(), expectedState); -} -#undef Pause -#undef Start -#undef Resume -#undef Stop - -void tst_QPropertyAnimation::oneKeyValue() -{ - QObject o; - o.setProperty("ole", 42); - QCOMPARE(o.property("ole").toInt(), 42); - - QPropertyAnimation animation(&o, "ole"); - animation.setStartValue(43); - animation.setEndValue(44); - animation.setDuration(100); - - animation.setCurrentTime(0); - - QVERIFY(animation.currentValue().isValid()); - QCOMPARE(animation.currentValue().toInt(), 43); - QCOMPARE(o.property("ole").toInt(), 42); - - // remove the last key value - animation.setKeyValueAt(1.0, QVariant()); - - // we will neither interpolate, nor update the current value - // since there is only one 1 key value defined - animation.setCurrentTime(100); - - // the animation should not have been modified - QVERIFY(animation.currentValue().isValid()); - QCOMPARE(animation.currentValue().toInt(), 43); - QCOMPARE(o.property("ole").toInt(), 42); -} - -void tst_QPropertyAnimation::updateOnSetKeyValues() -{ - QObject o; - o.setProperty("ole", 100); - QCOMPARE(o.property("ole").toInt(), 100); - - QPropertyAnimation animation(&o, "ole"); - animation.setStartValue(100); - animation.setEndValue(200); - animation.setDuration(100); - - animation.setCurrentTime(50); - QCOMPARE(animation.currentValue().toInt(), 150); - animation.setKeyValueAt(0.0, 300); - QCOMPARE(animation.currentValue().toInt(), 250); - - o.setProperty("ole", 100); - QPropertyAnimation animation2(&o, "ole"); - QVariantAnimation::KeyValues kValues; - kValues << QVariantAnimation::KeyValue(0.0, 100) << QVariantAnimation::KeyValue(1.0, 200); - animation2.setKeyValues(kValues); - animation2.setDuration(100); - animation2.setCurrentTime(50); - QCOMPARE(animation2.currentValue().toInt(), 150); - - kValues.clear(); - kValues << QVariantAnimation::KeyValue(0.0, 300) << QVariantAnimation::KeyValue(1.0, 200); - animation2.setKeyValues(kValues); - - QCOMPARE(animation2.currentValue().toInt(), animation.currentValue().toInt()); -} - -QTEST_MAIN(tst_QPropertyAnimation) -#include "tst_qpropertyanimation.moc" diff --git a/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro b/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro deleted file mode 100644 index ad861c3..0000000 --- a/tests/auto/qsequentialanimationgroup/qsequentialanimationgroup.pro +++ /dev/null @@ -1,5 +0,0 @@ -load(qttest_p4) -QT = core gui -SOURCES += tst_qsequentialanimationgroup.cpp - - diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp deleted file mode 100644 index 0631343..0000000 --- a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp +++ /dev/null @@ -1,1649 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "../../shared/util.h" - -#include -#include - -//TESTED_CLASS=QSequentialAnimationGroup -//TESTED_FILES= - -Q_DECLARE_METATYPE(QAbstractAnimation::State) -Q_DECLARE_METATYPE(QAbstractAnimation*) - -class tst_QSequentialAnimationGroup : public QObject -{ - Q_OBJECT -public: - tst_QSequentialAnimationGroup(); - virtual ~tst_QSequentialAnimationGroup(); - -public Q_SLOTS: - void init(); - void cleanup(); - -private slots: - void construction(); - void setCurrentTime(); - void setCurrentTimeWithUncontrolledAnimation(); - void seekingForwards(); - void seekingBackwards(); - void pauseAndResume(); - void restart(); - void looping(); - void startDelay(); - void clearGroup(); - void groupWithZeroDurationAnimations(); - void propagateGroupUpdateToChildren(); - void updateChildrenWithRunningGroup(); - void deleteChildrenWithRunningGroup(); - void startChildrenWithStoppedGroup(); - void stopGroupWithRunningChild(); - void startGroupWithRunningChild(); - void zeroDurationAnimation(); - void stopUncontrolledAnimations(); - void finishWithUncontrolledAnimation(); - void addRemoveAnimation(); - void currentAnimation(); - void currentAnimationWithZeroDuration(); - void insertAnimation(); - void clearAnimations(); -}; - -tst_QSequentialAnimationGroup::tst_QSequentialAnimationGroup() -{ -} - -tst_QSequentialAnimationGroup::~tst_QSequentialAnimationGroup() -{ -} - -void tst_QSequentialAnimationGroup::init() -{ - qRegisterMetaType("QAbstractAnimation::State"); - qRegisterMetaType("QAbstractAnimation*"); -} - -void tst_QSequentialAnimationGroup::cleanup() -{ -} - -void tst_QSequentialAnimationGroup::construction() -{ - QSequentialAnimationGroup animationgroup; -} - -class AnimationObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(int value READ value WRITE setValue) -public: - AnimationObject(int startValue = 0) - : v(startValue) - { } - - int value() const { return v; } - void setValue(int value) { v = value; } - - int v; -}; - -class TestAnimation : public QVariantAnimation -{ - Q_OBJECT -public: - virtual void updateCurrentValue(const QVariant &value) { Q_UNUSED(value)}; - virtual void updateState(QAbstractAnimation::State oldState, - QAbstractAnimation::State newState) - { - Q_UNUSED(oldState) - Q_UNUSED(newState) - }; -}; - -class UncontrolledAnimation : public QPropertyAnimation -{ - Q_OBJECT -public: - UncontrolledAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0) - : QPropertyAnimation(target, propertyName, parent) - { - setDuration(250); - } - - int duration() const { return -1; /* not time driven */ } - -protected: - void updateCurrentTime(int msecs) - { - QPropertyAnimation::updateCurrentTime(msecs); - if (msecs >= QPropertyAnimation::duration()) - stop(); - } -}; - -void tst_QSequentialAnimationGroup::setCurrentTime() -{ - AnimationObject s_o1; - AnimationObject s_o2; - AnimationObject s_o3; - - // sequence operating on same object/property - QAnimationGroup *sequence = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setLoopCount(3); - sequence->addAnimation(a1_s_o1); - sequence->addAnimation(a2_s_o1); - sequence->addAnimation(a3_s_o1); - - // sequence operating on different object/properties - QAnimationGroup *sequence2 = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); - QVariantAnimation *a1_s_o3 = new QPropertyAnimation(&s_o3, "value"); - sequence2->addAnimation(a1_s_o2); - sequence2->addAnimation(a1_s_o3); - - QSequentialAnimationGroup group; - group.addAnimation(sequence); - group.addAnimation(sequence2); - - // Current time = 1 - group.setCurrentTime(1); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(sequence->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - - QCOMPARE(group.currentTime(), 1); - QCOMPARE(sequence->currentTime(), 1); - QCOMPARE(a1_s_o1->currentTime(), 1); - QCOMPARE(a2_s_o1->currentTime(), 0); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // Current time = 250 - group.setCurrentTime(250); - QCOMPARE(group.currentTime(), 250); - QCOMPARE(sequence->currentTime(), 250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 0); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // Current time = 251 - group.setCurrentTime(251); - QCOMPARE(group.currentTime(), 251); - QCOMPARE(sequence->currentTime(), 251); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 1); - QCOMPARE(a2_s_o1->currentLoop(), 0); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(sequence2->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // Current time = 750 - group.setCurrentTime(750); - QCOMPARE(group.currentTime(), 750); - QCOMPARE(sequence->currentTime(), 750); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 0); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(sequence2->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // Current time = 1000 - group.setCurrentTime(1000); - QCOMPARE(group.currentTime(), 1000); - QCOMPARE(sequence->currentTime(), 1000); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(sequence2->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // Current time = 1010 - group.setCurrentTime(1010); - QCOMPARE(group.currentTime(), 1010); - QCOMPARE(sequence->currentTime(), 1010); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 10); - QCOMPARE(sequence2->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // Current time = 1250 - group.setCurrentTime(1250); - QCOMPARE(group.currentTime(), 1250); - QCOMPARE(sequence->currentTime(), 1250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 250); - QCOMPARE(sequence2->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // Current time = 1500 - group.setCurrentTime(1500); - QCOMPARE(group.currentTime(), 1500); - QCOMPARE(sequence->currentTime(), 1250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 250); - QCOMPARE(sequence2->currentTime(), 250); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // Current time = 1750 - group.setCurrentTime(1750); - QCOMPARE(group.currentTime(), 1750); - QCOMPARE(sequence->currentTime(), 1250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 250); - QCOMPARE(sequence2->currentTime(), 500); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(a1_s_o3->currentTime(), 250); - - // Current time = 2000 - group.setCurrentTime(2000); - QCOMPARE(group.currentTime(), 1750); - QCOMPARE(sequence->currentTime(), 1250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 250); - QCOMPARE(sequence2->currentTime(), 500); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(a1_s_o3->currentTime(), 250); -} - -void tst_QSequentialAnimationGroup::setCurrentTimeWithUncontrolledAnimation() -{ - AnimationObject s_o1; - AnimationObject s_o2; - AnimationObject t_o1; - AnimationObject t_o2; - - // sequence operating on different object/properties - QAnimationGroup *sequence = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); - sequence->addAnimation(a1_s_o1); - sequence->addAnimation(a1_s_o2); - - UncontrolledAnimation *notTimeDriven = new UncontrolledAnimation(&t_o1, "value"); - QCOMPARE(notTimeDriven->totalDuration(), -1); - - QVariantAnimation *loopsForever = new QPropertyAnimation(&t_o2, "value"); - loopsForever->setLoopCount(-1); - QCOMPARE(loopsForever->totalDuration(), -1); - - QSequentialAnimationGroup group; - group.addAnimation(sequence); - group.addAnimation(notTimeDriven); - group.addAnimation(loopsForever); - group.start(); - group.pause(); // this allows the group to listen for the finish signal of its children - - // Current time = 1 - group.setCurrentTime(1); - QCOMPARE(group.state(), QAnimationGroup::Paused); - QCOMPARE(sequence->state(), QAnimationGroup::Paused); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); - QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); - - QCOMPARE(group.currentTime(), 1); - QCOMPARE(sequence->currentTime(), 1); - QCOMPARE(a1_s_o1->currentTime(), 1); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(notTimeDriven->currentTime(), 0); - QCOMPARE(loopsForever->currentTime(), 0); - - // Current time = 250 - group.setCurrentTime(250); - QCOMPARE(group.currentTime(), 250); - QCOMPARE(sequence->currentTime(), 250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(notTimeDriven->currentTime(), 0); - QCOMPARE(loopsForever->currentTime(), 0); - - // Current time = 500 - group.setCurrentTime(500); - QCOMPARE(group.currentTime(), 500); - QCOMPARE(sequence->currentTime(), 500); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(notTimeDriven->currentTime(), 0); - QCOMPARE(loopsForever->currentTime(), 0); - QCOMPARE(group.currentAnimation(), notTimeDriven); - - // Current time = 505 - group.setCurrentTime(505); - QCOMPARE(group.currentTime(), 505); - QCOMPARE(sequence->currentTime(), 500); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(notTimeDriven->currentTime(), 5); - QCOMPARE(loopsForever->currentTime(), 0); - QCOMPARE(group.currentAnimation(), notTimeDriven); - QCOMPARE(sequence->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(notTimeDriven->state(), QAnimationGroup::Paused); - QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); - - // Current time = 750 (end of notTimeDriven animation) - group.setCurrentTime(750); - QCOMPARE(group.currentTime(), 750); - QCOMPARE(sequence->currentTime(), 500); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(notTimeDriven->currentTime(), 250); - QCOMPARE(loopsForever->currentTime(), 0); - QCOMPARE(group.currentAnimation(), loopsForever); - QCOMPARE(sequence->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); - QCOMPARE(loopsForever->state(), QAnimationGroup::Paused); - - // Current time = 800 (as notTimeDriven was finished at 750, loopsforever should still run) - group.setCurrentTime(800); - QCOMPARE(group.currentTime(), 800); - QCOMPARE(group.currentAnimation(), loopsForever); - QCOMPARE(sequence->currentTime(), 500); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(notTimeDriven->currentTime(), 250); - QCOMPARE(loopsForever->currentTime(), 50); - - loopsForever->stop(); // this should stop the group - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(sequence->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(notTimeDriven->state(), QAnimationGroup::Stopped); - QCOMPARE(loopsForever->state(), QAnimationGroup::Stopped); -} - -void tst_QSequentialAnimationGroup::seekingForwards() -{ - AnimationObject s_o1; - AnimationObject s_o2; - AnimationObject s_o3; - - // sequence operating on same object/property - QAnimationGroup *sequence = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setLoopCount(3); - sequence->addAnimation(a1_s_o1); - sequence->addAnimation(a2_s_o1); - sequence->addAnimation(a3_s_o1); - - // sequence operating on different object/properties - QAnimationGroup *sequence2 = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); - QVariantAnimation *a1_s_o3 = new QPropertyAnimation(&s_o3, "value"); - sequence2->addAnimation(a1_s_o2); - sequence2->addAnimation(a1_s_o3); - - QSequentialAnimationGroup group; - group.addAnimation(sequence); - group.addAnimation(sequence2); - - // Current time = 1 - group.setCurrentTime(1); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(sequence->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped); - - QCOMPARE(group.currentTime(), 1); - QCOMPARE(sequence->currentTime(), 1); - QCOMPARE(a1_s_o1->currentTime(), 1); - QCOMPARE(a2_s_o1->currentTime(), 0); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(sequence2->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // Current time = 1500 - group.setCurrentTime(1500); - QCOMPARE(group.currentTime(), 1500); - QCOMPARE(sequence->currentTime(), 1250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 250); - QCOMPARE(sequence2->currentTime(), 250); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(a1_s_o3->currentTime(), 0); - - // this will restart the group - group.start(); - group.pause(); - QCOMPARE(group.state(), QAnimationGroup::Paused); - QCOMPARE(sequence->state(), QAnimationGroup::Paused); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused); - QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped); - - // Current time = 1750 - group.setCurrentTime(1750); - QCOMPARE(group.currentTime(), 1750); - QCOMPARE(sequence->currentTime(), 1250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 250); - QCOMPARE(sequence2->currentTime(), 500); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(a1_s_o3->currentTime(), 250); -} - -void tst_QSequentialAnimationGroup::seekingBackwards() -{ - AnimationObject s_o1; - AnimationObject s_o2; - AnimationObject s_o3; - - // sequence operating on same object/property - QAnimationGroup *sequence = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setLoopCount(3); - sequence->addAnimation(a1_s_o1); - sequence->addAnimation(a2_s_o1); - sequence->addAnimation(a3_s_o1); - - // sequence operating on different object/properties - QAnimationGroup *sequence2 = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o2 = new QPropertyAnimation(&s_o2, "value"); - QVariantAnimation *a1_s_o3 = new QPropertyAnimation(&s_o3, "value"); - sequence2->addAnimation(a1_s_o2); - sequence2->addAnimation(a1_s_o3); - - QSequentialAnimationGroup group; - group.addAnimation(sequence); - group.addAnimation(sequence2); - - group.start(); - - // Current time = 1600 - group.setCurrentTime(1600); - QCOMPARE(group.currentTime(), 1600); - QCOMPARE(sequence->currentTime(), 1250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 250); - QCOMPARE(sequence2->currentTime(), 350); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(a1_s_o3->currentTime(), 100); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(sequence->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(sequence2->state(), QAnimationGroup::Running); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o3->state(), QAnimationGroup::Running); - - // Seeking backwards, current time = 1 - group.setCurrentTime(1); - QCOMPARE(group.currentTime(), 1); - QCOMPARE(sequence->currentTime(), 1); - QCOMPARE(a1_s_o1->currentTime(), 1); - - QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children," - "hence they don't reset from their current animation", Continue); - QCOMPARE(a2_s_o1->currentTime(), 0); - QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children," - "hence they don't reset from their current animation", Continue); - QCOMPARE(a2_s_o1->currentLoop(), 0); - QEXPECT_FAIL("", "rewinding in nested groups is considered as a restart from the children," - "hence they don't reset from their current animation", Continue); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(sequence2->currentTime(), 0); - QCOMPARE(a1_s_o2->currentTime(), 0); - QCOMPARE(a1_s_o3->currentTime(), 0); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(sequence->state(), QAnimationGroup::Running); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Running); - QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped); - - // Current time = 2000 - group.setCurrentTime(2000); - QCOMPARE(group.currentTime(), 1750); - QCOMPARE(sequence->currentTime(), 1250); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 2); - QCOMPARE(a3_s_o1->currentTime(), 250); - QCOMPARE(sequence2->currentTime(), 500); - QCOMPARE(a1_s_o2->currentTime(), 250); - QCOMPARE(a1_s_o3->currentTime(), 250); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(sequence->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(sequence2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o2->state(), QAnimationGroup::Stopped); - QCOMPARE(a1_s_o3->state(), QAnimationGroup::Stopped); -} - -typedef QList StateList; - -static bool compareStates(const QSignalSpy& spy, const StateList &expectedStates) -{ - bool equals = true; - for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) { - if (i >= spy.count() || i >= expectedStates.count()) { - equals = false; - break; - } - QList args = spy.at(i); - QAbstractAnimation::State st = expectedStates.at(i); - QAbstractAnimation::State actual = qVariantValue(args.value(1)); - if (equals && actual != st) { - equals = false; - break; - } - } - if (!equals) { - const char *stateStrings[] = {"Stopped", "Paused", "Running"}; - QString e,a; - for (int i = 0; i < qMax(expectedStates.count(), spy.count()); ++i) { - if (i < expectedStates.count()) { - int exp = int(expectedStates.at(i)); - if (!e.isEmpty()) - e += QLatin1String(", "); - e += QLatin1String(stateStrings[exp]); - } - if (i < spy.count()) { - QList args = spy.at(i); - QAbstractAnimation::State actual = qVariantValue(args.value(1)); - if (!a.isEmpty()) - a += QLatin1String(", "); - if (int(actual) >= 0 && int(actual) <= 2) { - a += QLatin1String(stateStrings[int(actual)]); - } else { - a += QLatin1String("NaN"); - } - } - - } - qDebug("\n" - "expected (count == %d): %s\n" - "actual (count == %d): %s\n", expectedStates.count(), qPrintable(e), spy.count(), qPrintable(a)); - } - return equals; -} - -void tst_QSequentialAnimationGroup::pauseAndResume() -{ - AnimationObject s_o1; - - // sequence operating on same object/property - QAnimationGroup *sequence = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - a2_s_o1->setLoopCount(2); - sequence->addAnimation(a1_s_o1); - sequence->addAnimation(a2_s_o1); - sequence->addAnimation(a3_s_o1); - sequence->setLoopCount(2); - - QSignalSpy a1StateChangedSpy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - QSequentialAnimationGroup group; - group.addAnimation(sequence); - - group.start(); - group.pause(); - - // Current time = 1751 - group.setCurrentTime(1751); - QCOMPARE(group.currentTime(), 1751); - QCOMPARE(sequence->currentTime(), 751); - QCOMPARE(sequence->currentLoop(), 1); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 1); - QCOMPARE(a3_s_o1->currentLoop(), 0); - QCOMPARE(a3_s_o1->currentTime(), 1); - - QCOMPARE(group.state(), QAnimationGroup::Paused); - QCOMPARE(sequence->state(), QAnimationGroup::Paused); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused); - - QCOMPARE(a1StateChangedSpy.count(), 5); // Running,Paused,Stopped,Running,Stopped - QCOMPARE(seqStateChangedSpy.count(), 2); // Running,Paused - - QVERIFY(compareStates(a1StateChangedSpy, (StateList() << QAbstractAnimation::Running - << QAbstractAnimation::Paused - << QAbstractAnimation::Stopped - << QAbstractAnimation::Running - << QAbstractAnimation::Stopped))); - - QCOMPARE(qVariantValue(a1StateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(a1StateChangedSpy.at(1).at(1)), - QAnimationGroup::Paused); - QCOMPARE(qVariantValue(a1StateChangedSpy.at(2).at(1)), - QAnimationGroup::Stopped); - QCOMPARE(qVariantValue(a1StateChangedSpy.at(3).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(a1StateChangedSpy.at(4).at(1)), - QAnimationGroup::Stopped); - - QCOMPARE(qVariantValue(seqStateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(seqStateChangedSpy.at(1).at(1)), - QAnimationGroup::Paused); - - group.resume(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(sequence->state(), QAnimationGroup::Running); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a3_s_o1->state(), QAnimationGroup::Running); - - QVERIFY(group.currentTime() >= 1751); - QVERIFY(sequence->currentTime() >= 751); - QCOMPARE(sequence->currentLoop(), 1); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 1); - QCOMPARE(a3_s_o1->currentLoop(), 0); - QVERIFY(a3_s_o1->currentTime() >= 1); - - QCOMPARE(seqStateChangedSpy.count(), 3); // Running,Paused,Running - QCOMPARE(qVariantValue(seqStateChangedSpy.at(2).at(1)), - QAnimationGroup::Running); - - group.pause(); - - QCOMPARE(group.state(), QAnimationGroup::Paused); - QCOMPARE(sequence->state(), QAnimationGroup::Paused); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused); - - QVERIFY(group.currentTime() >= 1751); - QVERIFY(sequence->currentTime() >= 751); - QCOMPARE(sequence->currentLoop(), 1); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 1); - QCOMPARE(a3_s_o1->currentLoop(), 0); - QVERIFY(a3_s_o1->currentTime() >= 1); - - QCOMPARE(seqStateChangedSpy.count(), 4); // Running,Paused,Running,Paused - QCOMPARE(qVariantValue(seqStateChangedSpy.at(3).at(1)), - QAnimationGroup::Paused); - - group.stop(); - - QCOMPARE(seqStateChangedSpy.count(), 5); // Running,Paused,Running,Paused,Stopped - QCOMPARE(qVariantValue(seqStateChangedSpy.at(4).at(1)), - QAnimationGroup::Stopped); -} - -void tst_QSequentialAnimationGroup::restart() -{ - AnimationObject s_o1; - - // sequence operating on same object/property - QAnimationGroup *sequence = new QSequentialAnimationGroup(); - QSignalSpy seqCurrentAnimChangedSpy(sequence, SIGNAL(currentAnimationChanged(QAbstractAnimation*))); - QSignalSpy seqStateChangedSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - QVariantAnimation *anims[3]; - QSignalSpy *animsStateChanged[3]; - - for (int i = 0; i < 3; i++) { - anims[i] = new QPropertyAnimation(&s_o1, "value"); - anims[i]->setDuration(100); - animsStateChanged[i] = new QSignalSpy(anims[i], SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - } - - anims[1]->setLoopCount(2); - sequence->addAnimation(anims[0]); - sequence->addAnimation(anims[1]); - sequence->addAnimation(anims[2]); - sequence->setLoopCount(2); - - QSequentialAnimationGroup group; - group.addAnimation(sequence); - - group.start(); - - QTest::qWait(500); - - QCOMPARE(group.state(), QAnimationGroup::Running); - - QTest::qWait(300); - QTRY_COMPARE(group.state(), QAnimationGroup::Stopped); - - for (int i = 0; i < 3; i++) { - QCOMPARE(animsStateChanged[i]->count(), 4); - QCOMPARE(qVariantValue(animsStateChanged[i]->at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(animsStateChanged[i]->at(1).at(1)), - QAnimationGroup::Stopped); - QCOMPARE(qVariantValue(animsStateChanged[i]->at(2).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(animsStateChanged[i]->at(3).at(1)), - QAnimationGroup::Stopped); - } - - QCOMPARE(seqStateChangedSpy.count(), 2); - QCOMPARE(qVariantValue(seqStateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(seqStateChangedSpy.at(1).at(1)), - QAnimationGroup::Stopped); - - QCOMPARE(seqCurrentAnimChangedSpy.count(), 6); - for(int i=0; i(seqCurrentAnimChangedSpy.at(i).at(0))); - - group.start(); - - QCOMPARE(animsStateChanged[0]->count(), 5); - QCOMPARE(animsStateChanged[1]->count(), 4); - QCOMPARE(animsStateChanged[2]->count(), 4); - QCOMPARE(seqStateChangedSpy.count(), 3); -} - -void tst_QSequentialAnimationGroup::looping() -{ - AnimationObject s_o1; - AnimationObject s_o2; - AnimationObject s_o3; - - // sequence operating on same object/property - QSequentialAnimationGroup *sequence = new QSequentialAnimationGroup(); - QVariantAnimation *a1_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a2_s_o1 = new QPropertyAnimation(&s_o1, "value"); - QVariantAnimation *a3_s_o1 = new QPropertyAnimation(&s_o1, "value"); - - QSignalSpy a1Spy(a1_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy a2Spy(a2_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy a3Spy(a3_s_o1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy seqSpy(sequence, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - a2_s_o1->setLoopCount(2); - sequence->addAnimation(a1_s_o1); - sequence->addAnimation(a2_s_o1); - sequence->addAnimation(a3_s_o1); - sequence->setLoopCount(2); - - QSequentialAnimationGroup group; - QSignalSpy groupSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - group.addAnimation(sequence); - group.setLoopCount(2); - - group.start(); - group.pause(); - - // Current time = 1750 - group.setCurrentTime(1750); - QCOMPARE(group.currentTime(), 1750); - QCOMPARE(sequence->currentTime(), 750); - QCOMPARE(sequence->currentLoop(), 1); - QCOMPARE(a1_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 1); - // this animation is at the beginning because it is the current one inside sequence - QCOMPARE(a3_s_o1->currentLoop(), 0); - QCOMPARE(a3_s_o1->currentTime(), 0); - QCOMPARE(sequence->currentAnimation(), a3_s_o1); - - QCOMPARE(group.state(), QAnimationGroup::Paused); - QCOMPARE(sequence->state(), QAnimationGroup::Paused); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a3_s_o1->state(), QAnimationGroup::Paused); - - QCOMPARE(a1Spy.count(), 5); // Running,Paused,Stopped,Running,Stopped - QVERIFY(compareStates(a1Spy, (StateList() << QAbstractAnimation::Running - << QAbstractAnimation::Paused - << QAbstractAnimation::Stopped - << QAbstractAnimation::Running - << QAbstractAnimation::Stopped))); - - QCOMPARE(a2Spy.count(), 4); // Running,Stopped,Running,Stopped - QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running - << QAbstractAnimation::Stopped - << QAbstractAnimation::Running - << QAbstractAnimation::Paused))); - - QCOMPARE(seqSpy.count(), 2); // Running,Paused - QCOMPARE(groupSpy.count(), 2); // Running,Paused - - // Looping, current time = duration + 1 - group.setCurrentTime(group.duration() + 1); - QCOMPARE(group.currentTime(), 1); - QCOMPARE(group.currentLoop(), 1); - QCOMPARE(sequence->currentTime(), 1); - QCOMPARE(sequence->currentLoop(), 0); - QCOMPARE(a1_s_o1->currentTime(), 1); - QCOMPARE(a2_s_o1->currentTime(), 250); - QCOMPARE(a2_s_o1->currentLoop(), 1); - // this animation is at the end because it was run on the previous loop - QCOMPARE(a3_s_o1->currentLoop(), 0); - QCOMPARE(a3_s_o1->currentTime(), 250); - - QCOMPARE(group.state(), QAnimationGroup::Paused); - QCOMPARE(sequence->state(), QAnimationGroup::Paused); - QCOMPARE(a1_s_o1->state(), QAnimationGroup::Paused); - QCOMPARE(a2_s_o1->state(), QAnimationGroup::Stopped); - QCOMPARE(a3_s_o1->state(), QAnimationGroup::Stopped); - - QCOMPARE(a1Spy.count(), 7); // Running,Paused,Stopped,Running,Stopped,Running,Stopped - QCOMPARE(a2Spy.count(), 4); // Running, Stopped, Running, Stopped - QVERIFY(compareStates(a3Spy, (StateList() << QAbstractAnimation::Running - << QAbstractAnimation::Stopped - << QAbstractAnimation::Running - << QAbstractAnimation::Paused - << QAbstractAnimation::Stopped))); - QVERIFY(compareStates(seqSpy, (StateList() << QAbstractAnimation::Running - << QAbstractAnimation::Paused - << QAbstractAnimation::Stopped - << QAbstractAnimation::Running - << QAbstractAnimation::Paused))); - QCOMPARE(groupSpy.count(), 2); -} - -void tst_QSequentialAnimationGroup::startDelay() -{ - QSequentialAnimationGroup group; - group.addPause(250); - group.addPause(125); - QCOMPARE(group.totalDuration(), 375); - - QEventLoop loop; - QObject::connect(&group, SIGNAL(finished()), &loop, SLOT(quit())); - - QTime time; - time.start(); - group.start(); - loop.exec(); - - QVERIFY(time.elapsed() >= 375); - QVERIFY(time.elapsed() < 1000); -} - -void tst_QSequentialAnimationGroup::clearGroup() -{ - QSequentialAnimationGroup group; - - for (int i = 0; i < 10; ++i) { - QSequentialAnimationGroup *subGroup = new QSequentialAnimationGroup(&group); - group.addPause(100); - subGroup->addPause(10); - } - - QCOMPARE(group.animationCount(), 20); - - int count = group.animationCount(); - QPointer *children = new QPointer[count]; - for (int i = 0; i < count; ++i) { - QVERIFY(group.animationAt(i) != 0); - children[i] = group.animationAt(i); - } - - group.clearAnimations(); - QCOMPARE(group.animationCount(), 0); - QCOMPARE(group.currentTime(), 0); - for (int i = 0; i < count; ++i) - QCOMPARE(children[i], QPointer()); - - delete[] children; -} - -void tst_QSequentialAnimationGroup::groupWithZeroDurationAnimations() -{ - QObject o; - QObject o2; - - o.setProperty("myProperty", 42); - o.setProperty("myOtherProperty", 13); - o2.setProperty("myProperty", 42); - o2.setProperty("myOtherProperty", 13); - - QSequentialAnimationGroup group; - - QVariantAnimation *a1 = new QPropertyAnimation(&o, "myProperty"); - a1->setDuration(0); - a1->setEndValue(43); - group.addAnimation(a1); - - //this should just run fine and change nothing - group.setCurrentTime(0); - QCOMPARE(group.currentAnimation(), a1); - - QVariantAnimation *a2 = new QPropertyAnimation(&o2, "myOtherProperty"); - a2->setDuration(500); - a2->setEndValue(31); - group.addAnimation(a2); - - QVariantAnimation *a3 = new QPropertyAnimation(&o, "myProperty"); - a3->setDuration(0); - a3->setEndValue(44); - group.addAnimation(a3); - - QVariantAnimation *a4 = new QPropertyAnimation(&o, "myOtherProperty"); - a4->setDuration(250); - a4->setEndValue(75); - group.addAnimation(a4); - - QVariantAnimation *a5 = new QPropertyAnimation(&o2, "myProperty"); - a5->setDuration(0); - a5->setEndValue(12); - group.addAnimation(a5); - - QCOMPARE(o.property("myProperty").toInt(), 42); - QCOMPARE(o.property("myOtherProperty").toInt(), 13); - QCOMPARE(o2.property("myProperty").toInt(), 42); - QCOMPARE(o2.property("myOtherProperty").toInt(), 13); - - - group.start(); - - QCOMPARE(o.property("myProperty").toInt(), 43); - QCOMPARE(o.property("myOtherProperty").toInt(), 13); - QCOMPARE(o2.property("myProperty").toInt(), 42); - QCOMPARE(o2.property("myOtherProperty").toInt(), 13); - - QTest::qWait(50); - - int o2val = o2.property("myOtherProperty").toInt(); - QVERIFY(o2val > 13); - QVERIFY(o2val < 31); - QCOMPARE(o.property("myProperty").toInt(), 43); - QCOMPARE(o.property("myOtherProperty").toInt(), 13); - - QTest::qWait(500); - - QCOMPARE(o.property("myProperty").toInt(), 44); - QCOMPARE(o2.property("myProperty").toInt(), 42); - QCOMPARE(o2.property("myOtherProperty").toInt(), 31); - QCOMPARE(a1->state(), QAnimationGroup::Stopped); - QCOMPARE(a2->state(), QAnimationGroup::Stopped); - QCOMPARE(a3->state(), QAnimationGroup::Stopped); - QCOMPARE(a4->state(), QAnimationGroup::Running); - QCOMPARE(a5->state(), QAnimationGroup::Stopped); - QCOMPARE(group.state(), QAnimationGroup::Running); - QTest::qWait(500); - - QTRY_COMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(o.property("myProperty").toInt(), 44); - QCOMPARE(o.property("myOtherProperty").toInt(), 75); - QCOMPARE(o2.property("myProperty").toInt(), 12); - QCOMPARE(o2.property("myOtherProperty").toInt(), 31); - QCOMPARE(a1->state(), QAnimationGroup::Stopped); - QCOMPARE(a2->state(), QAnimationGroup::Stopped); - QCOMPARE(a3->state(), QAnimationGroup::Stopped); - QCOMPARE(a4->state(), QAnimationGroup::Stopped); - QCOMPARE(a5->state(), QAnimationGroup::Stopped); -} - -void tst_QSequentialAnimationGroup::propagateGroupUpdateToChildren() -{ - // this test verifies if group state changes are updating its children correctly - QSequentialAnimationGroup group; - - QObject o; - o.setProperty("ole", 42); - QCOMPARE(o.property("ole").toInt(), 42); - - QPropertyAnimation anim1(&o, "ole"); - anim1.setEndValue(43); - anim1.setDuration(100); - QVERIFY(!anim1.currentValue().isValid()); - QCOMPARE(anim1.currentValue().toInt(), 0); - QCOMPARE(o.property("ole").toInt(), 42); - - TestAnimation anim2; - anim2.setStartValue(0); - anim2.setEndValue(100); - anim2.setDuration(200); - - QVERIFY(anim2.currentValue().isValid()); - QCOMPARE(anim2.currentValue().toInt(), 0); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - - group.start(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - group.pause(); - - QCOMPARE(group.state(), QAnimationGroup::Paused); - QCOMPARE(anim1.state(), QAnimationGroup::Paused); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - group.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); -} - -void tst_QSequentialAnimationGroup::updateChildrenWithRunningGroup() -{ - // assert that its possible to modify a child's state directly while their group is running - QSequentialAnimationGroup group; - - TestAnimation anim; - anim.setStartValue(0); - anim.setEndValue(100); - anim.setDuration(200); - - QSignalSpy groupStateChangedSpy(&group, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy childStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - QCOMPARE(groupStateChangedSpy.count(), 0); - QCOMPARE(childStateChangedSpy.count(), 0); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim.state(), QAnimationGroup::Stopped); - - group.addAnimation(&anim); - - group.start(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim.state(), QAnimationGroup::Running); - - QCOMPARE(groupStateChangedSpy.count(), 1); - QCOMPARE(childStateChangedSpy.count(), 1); - - QCOMPARE(qVariantValue(groupStateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(childStateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - - // starting directly a running child will not have any effect - anim.start(); - - QCOMPARE(groupStateChangedSpy.count(), 1); - QCOMPARE(childStateChangedSpy.count(), 1); - - anim.pause(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim.state(), QAnimationGroup::Paused); - - // in the animation stops directly, the group will still be running - anim.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim.state(), QAnimationGroup::Stopped); -} - -void tst_QSequentialAnimationGroup::deleteChildrenWithRunningGroup() -{ - // test if children can be activated when their group is stopped - QSequentialAnimationGroup group; - - QVariantAnimation *anim1 = new TestAnimation; - anim1->setStartValue(0); - anim1->setEndValue(100); - anim1->setDuration(200); - group.addAnimation(anim1); - - QCOMPARE(group.duration(), anim1->duration()); - - group.start(); - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim1->state(), QAnimationGroup::Running); - - QTest::qWait(50); - QVERIFY(group.currentTime() > 0); - - delete anim1; - QCOMPARE(group.animationCount(), 0); - QCOMPARE(group.duration(), 0); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(group.currentTime(), 0); //that's the invariant -} - -void tst_QSequentialAnimationGroup::startChildrenWithStoppedGroup() -{ - // test if children can be activated when their group is stopped - QSequentialAnimationGroup group; - - TestAnimation anim1; - anim1.setStartValue(0); - anim1.setEndValue(100); - anim1.setDuration(200); - - TestAnimation anim2; - anim2.setStartValue(0); - anim2.setEndValue(100); - anim2.setDuration(200); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - - group.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - anim1.start(); - anim2.start(); - anim2.pause(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Paused); -} - -void tst_QSequentialAnimationGroup::stopGroupWithRunningChild() -{ - // children that started independently will not be affected by a group stop - QSequentialAnimationGroup group; - - TestAnimation anim1; - anim1.setStartValue(0); - anim1.setEndValue(100); - anim1.setDuration(200); - - TestAnimation anim2; - anim2.setStartValue(0); - anim2.setEndValue(100); - anim2.setDuration(200); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); - - group.addAnimation(&anim1); - group.addAnimation(&anim2); - - anim1.start(); - anim2.start(); - anim2.pause(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Paused); - - group.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Running); - QCOMPARE(anim2.state(), QAnimationGroup::Paused); - - anim1.stop(); - anim2.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1.state(), QAnimationGroup::Stopped); - QCOMPARE(anim2.state(), QAnimationGroup::Stopped); -} - -void tst_QSequentialAnimationGroup::startGroupWithRunningChild() -{ - // as the group has precedence over its children, starting a group will restart all the children - QSequentialAnimationGroup group; - - TestAnimation *anim1 = new TestAnimation(); - anim1->setStartValue(0); - anim1->setEndValue(100); - anim1->setDuration(200); - - TestAnimation *anim2 = new TestAnimation(); - anim2->setStartValue(0); - anim2->setEndValue(100); - anim2->setDuration(200); - - QSignalSpy stateChangedSpy1(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - QSignalSpy stateChangedSpy2(anim2, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - QCOMPARE(stateChangedSpy1.count(), 0); - QCOMPARE(stateChangedSpy2.count(), 0); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1->state(), QAnimationGroup::Stopped); - QCOMPARE(anim2->state(), QAnimationGroup::Stopped); - - group.addAnimation(anim1); - group.addAnimation(anim2); - - anim1->start(); - anim2->start(); - anim2->pause(); - - QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running))); - - QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running - << QAbstractAnimation::Paused))); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1->state(), QAnimationGroup::Running); - QCOMPARE(anim2->state(), QAnimationGroup::Paused); - - group.start(); - - QVERIFY(compareStates(stateChangedSpy1, (StateList() << QAbstractAnimation::Running - << QAbstractAnimation::Stopped - << QAbstractAnimation::Running))); - QVERIFY(compareStates(stateChangedSpy2, (StateList() << QAbstractAnimation::Running - << QAbstractAnimation::Paused))); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim1->state(), QAnimationGroup::Running); - QCOMPARE(anim2->state(), QAnimationGroup::Paused); - - QTest::qWait(300); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim1->state(), QAnimationGroup::Stopped); - QCOMPARE(anim2->state(), QAnimationGroup::Running); - - QCOMPARE(stateChangedSpy2.count(), 4); - QCOMPARE(qVariantValue(stateChangedSpy2.at(2).at(1)), - QAnimationGroup::Stopped); - QCOMPARE(qVariantValue(stateChangedSpy2.at(3).at(1)), - QAnimationGroup::Running); - - group.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(anim1->state(), QAnimationGroup::Stopped); - QCOMPARE(anim2->state(), QAnimationGroup::Stopped); -} - -void tst_QSequentialAnimationGroup::zeroDurationAnimation() -{ - QSequentialAnimationGroup group; - - TestAnimation *anim1 = new TestAnimation(); - anim1->setStartValue(0); - anim1->setEndValue(100); - anim1->setDuration(0); - - TestAnimation *anim2 = new TestAnimation(); - anim2->setStartValue(0); - anim2->setEndValue(100); - anim2->setDuration(100); - - AnimationObject o1; - QPropertyAnimation *anim3 = new QPropertyAnimation(&o1, "value"); - anim3->setEndValue(100); - anim3->setDuration(0); - - QSignalSpy stateChangedSpy(anim1, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - group.addAnimation(anim1); - group.addAnimation(anim2); - group.addAnimation(anim3); - group.setLoopCount(2); - group.start(); - - QCOMPARE(stateChangedSpy.count(), 2); - QCOMPARE(qVariantValue(stateChangedSpy.at(0).at(1)), - QAnimationGroup::Running); - QCOMPARE(qVariantValue(stateChangedSpy.at(1).at(1)), - QAnimationGroup::Stopped); - - QCOMPARE(anim1->state(), QAnimationGroup::Stopped); - QCOMPARE(anim2->state(), QAnimationGroup::Running); - QCOMPARE(group.state(), QAnimationGroup::Running); - - //now let's try to seek to the next loop - group.setCurrentTime(group.duration() + 1); - QCOMPARE(anim1->state(), QAnimationGroup::Stopped); - QCOMPARE(anim2->state(), QAnimationGroup::Running); - QCOMPARE(anim3->state(), QAnimationGroup::Stopped); - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(o1.value(), 100); //anim3 should have been run -} - -void tst_QSequentialAnimationGroup::stopUncontrolledAnimations() -{ - QSequentialAnimationGroup group; - - AnimationObject o1; - UncontrolledAnimation notTimeDriven(&o1, "value"); - QCOMPARE(notTimeDriven.totalDuration(), -1); - - TestAnimation loopsForever; - loopsForever.setStartValue(0); - loopsForever.setEndValue(100); - loopsForever.setDuration(100); - loopsForever.setLoopCount(-1); - - group.addAnimation(¬TimeDriven); - group.addAnimation(&loopsForever); - - group.start(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running); - QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped); - - notTimeDriven.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); - QCOMPARE(loopsForever.state(), QAnimationGroup::Running); - - loopsForever.stop(); - - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); - QCOMPARE(loopsForever.state(), QAnimationGroup::Stopped); -} - -void tst_QSequentialAnimationGroup::finishWithUncontrolledAnimation() -{ - AnimationObject o1; - - //1st case: - //first we test a group with one uncontrolled animation - QSequentialAnimationGroup group; - UncontrolledAnimation notTimeDriven(&o1, "value", &group); - QSignalSpy spy(&group, SIGNAL(finished())); - - group.start(); - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running); - QCOMPARE(group.currentTime(), 0); - QCOMPARE(notTimeDriven.currentTime(), 0); - - QTest::qWait(300); //wait for the end of notTimeDriven - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); - const int actualDuration = notTimeDriven.currentTime(); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(group.currentTime(), actualDuration); - QCOMPARE(spy.count(), 1); - - //2nd case: - // lets make sure the seeking will work again - spy.clear(); - QPropertyAnimation anim(&group); - QSignalSpy animStateChangedSpy(&anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); - - group.setCurrentTime(300); - QCOMPARE(group.state(), QAnimationGroup::Stopped); - QCOMPARE(notTimeDriven.currentTime(), actualDuration); - QCOMPARE(group.currentAnimation(), &anim); - - //3rd case: - //now let's add a perfectly defined animation at the end - QCOMPARE(animStateChangedSpy.count(), 0); - group.start(); - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Running); - QCOMPARE(group.currentTime(), 0); - QCOMPARE(notTimeDriven.currentTime(), 0); - - QCOMPARE(animStateChangedSpy.count(), 0); - - QTest::qWait(300); //wait for the end of notTimeDriven - QCOMPARE(notTimeDriven.state(), QAnimationGroup::Stopped); - QCOMPARE(group.state(), QAnimationGroup::Running); - QCOMPARE(anim.state(), QAnimationGroup::Running); - QCOMPARE(group.currentAnimation(), &anim); - QCOMPARE(animStateChangedSpy.count(), 1); - QTest::qWait(300); //wait for the end of anim - - QCOMPARE(anim.state(), QAnimationGroup::Stopped); - QCOMPARE(anim.currentTime(), anim.duration()); - - //we should simply be at the end - QCOMPARE(spy.count(), 1); - QCOMPARE(animStateChangedSpy.count(), 2); - QCOMPARE(group.currentTime(), notTimeDriven.currentTime() + anim.currentTime()); -} - -void tst_QSequentialAnimationGroup::addRemoveAnimation() -{ - //this test is specific to the sequential animation group - QSequentialAnimationGroup group; - - QCOMPARE(group.duration(), 0); - QCOMPARE(group.currentTime(), 0); - QVariantAnimation *anim1 = new QPropertyAnimation; - group.addAnimation(anim1); - QCOMPARE(group.duration(), 250); - QCOMPARE(group.currentTime(), 0); - QCOMPARE(group.currentAnimation(), anim1); - - //let's append an animation - QVariantAnimation *anim2 = new QPropertyAnimation; - group.addAnimation(anim2); - QCOMPARE(group.duration(), 500); - QCOMPARE(group.currentTime(), 0); - QCOMPARE(group.currentAnimation(), anim1); - - //let's prepend an animation - QVariantAnimation *anim0 = new QPropertyAnimation; - group.insertAnimationAt(0, anim0); - QCOMPARE(group.duration(), 750); - QCOMPARE(group.currentTime(), 0); - QCOMPARE(group.currentAnimation(), anim0); //anim0 has become the new currentAnimation - - group.setCurrentTime(300); //anim0 | anim1 | anim2 - QCOMPARE(group.currentTime(), 300); - QCOMPARE(group.currentAnimation(), anim1); - QCOMPARE(anim1->currentTime(), 50); - - group.removeAnimation(anim0); //anim1 | anim2 - QCOMPARE(group.currentTime(), 50); - QCOMPARE(group.currentAnimation(), anim1); - QCOMPARE(anim1->currentTime(), 50); - - group.setCurrentTime(0); - group.insertAnimationAt(0, anim0); //anim0 | anim1 | anim2 - group.setCurrentTime(300); - QCOMPARE(group.currentTime(), 300); - QCOMPARE(group.currentAnimation(), anim1); - QCOMPARE(anim1->currentTime(), 50); - - group.removeAnimation(anim1); //anim0 | anim2 - QCOMPARE(group.currentTime(), 250); - QCOMPARE(group.currentAnimation(), anim2); - QCOMPARE(anim0->currentTime(), 250); -} - -void tst_QSequentialAnimationGroup::currentAnimation() -{ - QSequentialAnimationGroup group; - QVERIFY(group.currentAnimation() == 0); - - QPropertyAnimation anim; - anim.setDuration(0); - group.addAnimation(&anim); - QCOMPARE(group.currentAnimation(), &anim); -} - -void tst_QSequentialAnimationGroup::currentAnimationWithZeroDuration() -{ - QSequentialAnimationGroup group; - QVERIFY(group.currentAnimation() == 0); - - QPropertyAnimation zero1; - zero1.setDuration(0); - QPropertyAnimation zero2; - zero2.setDuration(0); - - QPropertyAnimation anim; - - QPropertyAnimation zero3; - zero3.setDuration(0); - QPropertyAnimation zero4; - zero4.setDuration(0); - - - group.addAnimation(&zero1); - group.addAnimation(&zero2); - group.addAnimation(&anim); - group.addAnimation(&zero3); - group.addAnimation(&zero4); - - QCOMPARE(group.currentAnimation(), &zero1); - - group.setCurrentTime(0); - QCOMPARE(group.currentAnimation(), &anim); - - group.setCurrentTime(group.duration()); - QCOMPARE(group.currentAnimation(), &zero4); - - group.setDirection(QAbstractAnimation::Backward); - - group.setCurrentTime(0); - QCOMPARE(group.currentAnimation(), &zero1); - - group.setCurrentTime(group.duration()); - QCOMPARE(group.currentAnimation(), &anim); -} - -void tst_QSequentialAnimationGroup::insertAnimation() -{ - QSequentialAnimationGroup group; - group.setLoopCount(2); - QPropertyAnimation *anim = new QPropertyAnimation(&group); - QCOMPARE(group.duration(), anim->duration()); - group.setCurrentTime(300); - QCOMPARE(group.currentLoop(), 1); - - //this will crash if the sequential group calls duration on the created animation - new QPropertyAnimation(&group); -} - - -class SequentialAnimationGroup : public QSequentialAnimationGroup -{ - Q_OBJECT -public slots: - void clearAnimations() - { - QSequentialAnimationGroup::clearAnimations(); - } - - void refill() - { - stop(); - clearAnimations(); - new QPropertyAnimation(this); - start(); - } - -}; - - -void tst_QSequentialAnimationGroup::clearAnimations() -{ - SequentialAnimationGroup group; - QPointer anim1 = new QPropertyAnimation(&group); - group.connect(anim1, SIGNAL(finished()), SLOT(clearAnimations())); - new QPropertyAnimation(&group); - QCOMPARE(group.animationCount(), 2); - - group.start(); - QTest::qWait(anim1->duration() + 100); - QCOMPARE(group.animationCount(), 0); - QCOMPARE(group.state(), QAbstractAnimation::Stopped); - QCOMPARE(group.currentTime(), 0); - - anim1 = new QPropertyAnimation(&group); - group.connect(anim1, SIGNAL(finished()), SLOT(refill())); - group.start(); - QTest::qWait(anim1->duration() + 100); - QVERIFY(anim1 == 0); //anim1 should have been deleted - QCOMPARE(group.state(), QAbstractAnimation::Running); -} - -QTEST_MAIN(tst_QSequentialAnimationGroup) -#include "tst_qsequentialanimationgroup.moc" diff --git a/tests/auto/qstate/qstate.pro b/tests/auto/qstate/qstate.pro deleted file mode 100644 index 9131fa8..0000000 --- a/tests/auto/qstate/qstate.pro +++ /dev/null @@ -1,5 +0,0 @@ -load(qttest_p4) -QT = core -SOURCES += tst_qstate.cpp - - diff --git a/tests/auto/qstate/tst_qstate.cpp b/tests/auto/qstate/tst_qstate.cpp deleted file mode 100644 index 75b1905..0000000 --- a/tests/auto/qstate/tst_qstate.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -****************************************************************************/ - -#include - -#include "qstate.h" -#include "qstatemachine.h" -#include "qsignaltransition.h" - -// Will try to wait for the condition while allowing event processing -#define QTRY_COMPARE(__expr, __expected) \ - do { \ - const int __step = 50; \ - const int __timeout = 5000; \ - if ((__expr) != (__expected)) { \ - QTest::qWait(0); \ - } \ - for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \ - QTest::qWait(__step); \ - } \ - QCOMPARE(__expr, __expected); \ - } while(0) - -//TESTED_CLASS= -//TESTED_FILES= - -class tst_QState : public QObject -{ - Q_OBJECT - -public: - tst_QState(); - virtual ~tst_QState(); - -private slots: -#if 0 - void test(); -#endif - void assignProperty(); - void assignPropertyTwice(); - void historyInitialState(); - -private: - bool functionCalled; -}; - -tst_QState::tst_QState() : functionCalled(false) -{ -} - -tst_QState::~tst_QState() -{ -} - -#if 0 -void tst_QState::test() -{ - QStateMachine machine; - QState *s1 = new QState(machine.rootState()); - - QCOMPARE(s1->machine(), &machine); - QCOMPARE(s1->parentState(), machine.rootState()); - QCOMPARE(s1->initialState(), (QState*)0); - QVERIFY(s1->childStates().isEmpty()); - QVERIFY(s1->transitions().isEmpty()); - - QCOMPARE(s1->isFinal(), false); - s1->setFinal(true); - QCOMPARE(s1->isFinal(), true); - s1->setFinal(false); - QCOMPARE(s1->isFinal(), false); - - QCOMPARE(s1->isParallel(), false); - s1->setParallel(true); - QCOMPARE(s1->isParallel(), true); - s1->setParallel(false); - QCOMPARE(s1->isParallel(), false); - - QCOMPARE(s1->isAtomic(), true); - QCOMPARE(s1->isCompound(), false); - QCOMPARE(s1->isComplex(), false); - - QState *s11 = new QState(s1); - QCOMPARE(s11->parentState(), s1); - QCOMPARE(s11->isAtomic(), true); - QCOMPARE(s11->isCompound(), false); - QCOMPARE(s11->isComplex(), false); - QCOMPARE(s11->machine(), s1->machine()); - QVERIFY(s11->isDescendantOf(s1)); - - QCOMPARE(s1->initialState(), (QState*)0); - QCOMPARE(s1->childStates().size(), 1); - QCOMPARE(s1->childStates().at(0), s11); - - QCOMPARE(s1->isAtomic(), false); - QCOMPARE(s1->isCompound(), true); - QCOMPARE(s1->isComplex(), true); - - s1->setParallel(true); - QCOMPARE(s1->isAtomic(), false); - QCOMPARE(s1->isCompound(), false); - QCOMPARE(s1->isComplex(), true); - - QState *s12 = new QState(s1); - QCOMPARE(s12->parentState(), s1); - QCOMPARE(s12->isAtomic(), true); - QCOMPARE(s12->isCompound(), false); - QCOMPARE(s12->isComplex(), false); - QCOMPARE(s12->machine(), s1->machine()); - QVERIFY(s12->isDescendantOf(s1)); - QVERIFY(!s12->isDescendantOf(s11)); - - QCOMPARE(s1->initialState(), (QState*)0); - QCOMPARE(s1->childStates().size(), 2); - QCOMPARE(s1->childStates().at(0), s11); - QCOMPARE(s1->childStates().at(1), s12); - - QCOMPARE(s1->isAtomic(), false); - QCOMPARE(s1->isCompound(), false); - QCOMPARE(s1->isComplex(), true); - - s1->setParallel(false); - QCOMPARE(s1->isAtomic(), false); - QCOMPARE(s1->isCompound(), true); - QCOMPARE(s1->isComplex(), true); - - s1->setInitialState(s11); - QCOMPARE(s1->initialState(), s11); - - s1->setInitialState(0); - QCOMPARE(s1->initialState(), (QState*)0); - - s1->setInitialState(s12); - QCOMPARE(s1->initialState(), s12); - - QState *s13 = new QState(); - s1->setInitialState(s13); - QCOMPARE(s13->parentState(), s1); - QCOMPARE(s1->childStates().size(), 3); - QCOMPARE(s1->childStates().at(0), s11); - QCOMPARE(s1->childStates().at(1), s12); - QCOMPARE(s1->childStates().at(2), s13); - QVERIFY(s13->isDescendantOf(s1)); - - QVERIFY(s12->childStates().isEmpty()); - - QState *s121 = new QState(s12); - QCOMPARE(s121->parentState(), s12); - QCOMPARE(s121->isAtomic(), true); - QCOMPARE(s121->isCompound(), false); - QCOMPARE(s121->isComplex(), false); - QCOMPARE(s121->machine(), s12->machine()); - QVERIFY(s121->isDescendantOf(s12)); - QVERIFY(s121->isDescendantOf(s1)); - QVERIFY(!s121->isDescendantOf(s11)); - - QCOMPARE(s12->childStates().size(), 1); - QCOMPARE(s12->childStates().at(0), (QState*)s121); - - QCOMPARE(s1->childStates().size(), 3); - QCOMPARE(s1->childStates().at(0), s11); - QCOMPARE(s1->childStates().at(1), s12); - QCOMPARE(s1->childStates().at(2), s13); - - s11->addTransition(s12); - QCOMPARE(s11->transitions().size(), 1); - QCOMPARE(s11->transitions().at(0)->sourceState(), s11); - QCOMPARE(s11->transitions().at(0)->targetStates().size(), 1); - QCOMPARE(s11->transitions().at(0)->targetStates().at(0), s12); - QCOMPARE(s11->transitions().at(0)->eventType(), QEvent::None); - - QState *s14 = new QState(); - s12->addTransition(QList() << s13 << s14); - QCOMPARE(s12->transitions().size(), 1); - QCOMPARE(s12->transitions().at(0)->sourceState(), s12); - QCOMPARE(s12->transitions().at(0)->targetStates().size(), 2); - QCOMPARE(s12->transitions().at(0)->targetStates().at(0), s13); - QCOMPARE(s12->transitions().at(0)->targetStates().at(1), s14); - QCOMPARE(s12->transitions().at(0)->eventType(), QEvent::None); - - s13->addTransition(this, SIGNAL(destroyed()), s14); - QCOMPARE(s13->transitions().size(), 1); - QCOMPARE(s13->transitions().at(0)->sourceState(), s13); - QCOMPARE(s13->transitions().at(0)->targetStates().size(), 1); - QCOMPARE(s13->transitions().at(0)->targetStates().at(0), s14); - QCOMPARE(s13->transitions().at(0)->eventType(), QEvent::Signal); - QVERIFY(qobject_cast(s13->transitions().at(0)) != 0); - - delete s13->transitions().at(0); - QCOMPARE(s13->transitions().size(), 0); - - s12->addTransition(this, SIGNAL(destroyed()), s11); - QCOMPARE(s12->transitions().size(), 2); -} -#endif - -class TestClass: public QObject -{ - Q_OBJECT -public: - TestClass() : called(false) {} - bool called; - -public slots: - void slot() { called = true; } - - -}; - -void tst_QState::assignProperty() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("fooBar", 10); - - QState *s1 = new QState(machine.rootState()); - s1->assignProperty(object, "fooBar", 20); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("fooBar").toInt(), 20); -} - -void tst_QState::assignPropertyTwice() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("fooBar", 10); - - QState *s1 = new QState(machine.rootState()); - s1->assignProperty(object, "fooBar", 20); - s1->assignProperty(object, "fooBar", 30); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("fooBar").toInt(), 30); -} - -class EventTestTransition: public QAbstractTransition -{ -public: - EventTestTransition(QEvent::Type type, QState *targetState) - : QAbstractTransition(QList() << targetState), m_type(type) - { - } - -protected: - bool eventTest(QEvent *e) - { - return e->type() == m_type; - } - - void onTransition(QEvent *) {} - -private: - QEvent::Type m_type; - -}; - -void tst_QState::historyInitialState() -{ - QStateMachine machine; - - QState *s1 = new QState(machine.rootState()); - - QState *s2 = new QState(machine.rootState()); - QHistoryState *h1 = new QHistoryState(s2); - - s2->setInitialState(h1); - - QState *s3 = new QState(s2); - h1->setDefaultState(s3); - - QState *s4 = new QState(s2); - - s1->addTransition(new EventTestTransition(QEvent::User, s2)); - s2->addTransition(new EventTestTransition(QEvent::User, s1)); - s3->addTransition(new EventTestTransition(QEvent::Type(QEvent::User+1), s4)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s3)); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s3)); - - machine.postEvent(new QEvent(QEvent::Type(QEvent::User+1))); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s4)); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s4)); -} - - -QTEST_MAIN(tst_QState) -#include "tst_qstate.moc" diff --git a/tests/auto/qstatemachine/qstatemachine.pro b/tests/auto/qstatemachine/qstatemachine.pro deleted file mode 100644 index e5b32b5..0000000 --- a/tests/auto/qstatemachine/qstatemachine.pro +++ /dev/null @@ -1,4 +0,0 @@ -load(qttest_p4) -QT = core gui -SOURCES += tst_qstatemachine.cpp - diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp deleted file mode 100644 index 40c01bd..0000000 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ /dev/null @@ -1,3548 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include - -#include "qstatemachine.h" -#include "qstate.h" -#include "qhistorystate.h" -#include "qkeyeventtransition.h" -#include "qmouseeventtransition.h" -#include "private/qstate_p.h" -#include "private/qstatemachine_p.h" - -// Will try to wait for the condition while allowing event processing -#define QTRY_COMPARE(__expr, __expected) \ - do { \ - const int __step = 50; \ - const int __timeout = 5000; \ - if ((__expr) != (__expected)) { \ - QTest::qWait(0); \ - } \ - for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \ - QTest::qWait(__step); \ - } \ - QCOMPARE(__expr, __expected); \ - } while(0) - -//TESTED_CLASS= -//TESTED_FILES= - -static int globalTick; - -// Run exec for a maximum of TIMEOUT msecs -#define QCOREAPPLICATION_EXEC(TIMEOUT) \ -{ \ - QTimer timer; \ - timer.setSingleShot(true); \ - timer.setInterval(TIMEOUT); \ - timer.start(); \ - connect(&timer, SIGNAL(timeout()), QCoreApplication::instance(), SLOT(quit())); \ - QCoreApplication::exec(); \ -} - -class tst_QStateMachine : public QObject -{ - Q_OBJECT -public: - tst_QStateMachine(); - virtual ~tst_QStateMachine(); - -private slots: - void init(); - void cleanup(); - - void rootState(); - void addAndRemoveState(); - void stateEntryAndExit(); - void assignProperty(); - void assignPropertyWithAnimation(); - void postEvent(); - void stateFinished(); - void parallelStates(); - void allSourceToTargetConfigurations(); - void signalTransitions(); - void eventTransitions(); - void historyStates(); - void startAndStop(); - void targetStateWithNoParent(); - void targetStateDeleted(); - void transitionToRootState(); - void transitionEntersParent(); - - void defaultErrorState(); - void customGlobalErrorState(); - void customLocalErrorStateInBrokenState(); - void customLocalErrorStateInOtherState(); - void customLocalErrorStateInParentOfBrokenState(); - void customLocalErrorStateOverridesParent(); - void errorStateHasChildren(); - void errorStateHasErrors(); - void errorStateIsRootState(); - void errorStateEntersParentFirst(); - void customErrorStateIsNull(); - void clearError(); - void historyStateHasNowhereToGo(); - void historyStateAsInitialState(); - void brokenStateIsNeverEntered(); - void customErrorStateNotInGraph(); - void transitionToStateNotInGraph(); - void restoreProperties(); - - void defaultGlobalRestorePolicy(); - void globalRestorePolicySetToRestore(); - void globalRestorePolicySetToDoNotRestore(); - - //void restorePolicyNotInherited(); - //void mixedRestoreProperties(); - //void setRestorePolicyToDoNotRestore(); - //void setGlobalRestorePolicyToGlobalRestore(); - //void restorePolicyOnChildState(); - - void transitionWithParent(); - void transitionsFromParallelStateWithNoChildren(); - void parallelStateTransition(); - void parallelStateAssignmentsDone(); - void nestedRestoreProperties(); - void nestedRestoreProperties2(); - - void simpleAnimation(); - void twoAnimations(); - void twoAnimatedTransitions(); - void playAnimationTwice(); - void nestedTargetStateForAnimation(); - void animatedGlobalRestoreProperty(); - void specificTargetValueOfAnimation(); - - void addDefaultAnimation(); - void addDefaultAnimationWithUnusedAnimation(); - void removeDefaultAnimation(); - void overrideDefaultAnimationWithSpecific(); - -// void addDefaultAnimationForSource(); -// void addDefaultAnimationForTarget(); -// void removeDefaultAnimationForSource(); -// void removeDefaultAnimationForTarget(); -// void overrideDefaultAnimationWithSource(); -// void overrideDefaultAnimationWithTarget(); -// void overrideDefaultSourceAnimationWithSpecific(); -// void overrideDefaultTargetAnimationWithSpecific(); -// void overrideDefaultTargetAnimationWithSource(); -}; - -tst_QStateMachine::tst_QStateMachine() -{ -} - -tst_QStateMachine::~tst_QStateMachine() -{ -} - -class TestState : public QState -{ -public: - enum Event { - Entry, - Exit - }; - TestState(QState *parent) - : QState(parent) {} - QList > events; -protected: - virtual void onEntry(QEvent *) { - events.append(qMakePair(globalTick++, Entry)); - } - virtual void onExit(QEvent *) { - events.append(qMakePair(globalTick++, Exit)); - } -}; - -class TestTransition : public QAbstractTransition -{ -public: - TestTransition(QAbstractState *target) - : QAbstractTransition(QList() << target) {} - QList triggers; -protected: - virtual bool eventTest(QEvent *) { - return true; - } - virtual void onTransition(QEvent *) { - triggers.append(globalTick++); - } -}; - -void tst_QStateMachine::init() -{ -} - -void tst_QStateMachine::cleanup() -{ -} - -class EventTransition : public QAbstractTransition -{ -public: - EventTransition(QEvent::Type type, QAbstractState *target, QState *parent = 0) - : QAbstractTransition(QList() << target, parent), m_type(type) {} -protected: - virtual bool eventTest(QEvent *e) { - return (e->type() == m_type); - } - virtual void onTransition(QEvent *) {} -private: - QEvent::Type m_type; -}; - -void tst_QStateMachine::transitionToRootState() -{ - QStateMachine machine; - - QState *initialState = new QState(); - machine.addState(initialState); - machine.setInitialState(initialState); - - QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::setTargetStates: root state cannot be target of transition"); - initialState->addTransition(new EventTransition(QEvent::User, machine.rootState())); - - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(initialState)); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(initialState)); -} - -void tst_QStateMachine::transitionEntersParent() -{ - QStateMachine machine; - - QObject *entryController = new QObject(&machine); - entryController->setObjectName("entryController"); - entryController->setProperty("greatGrandParentEntered", false); - entryController->setProperty("grandParentEntered", false); - entryController->setProperty("parentEntered", false); - entryController->setProperty("stateEntered", false); - - QState *greatGrandParent = new QState(); - greatGrandParent->setObjectName("grandParent"); - greatGrandParent->assignProperty(entryController, "greatGrandParentEntered", true); - machine.addState(greatGrandParent); - machine.setInitialState(greatGrandParent); - - QState *grandParent = new QState(greatGrandParent); - grandParent->setObjectName("grandParent"); - grandParent->assignProperty(entryController, "grandParentEntered", true); - - QState *parent = new QState(grandParent); - parent->setObjectName("parent"); - parent->assignProperty(entryController, "parentEntered", true); - - QState *state = new QState(parent); - state->setObjectName("state"); - state->assignProperty(entryController, "stateEntered", true); - - QState *initialStateOfGreatGrandParent = new QState(greatGrandParent); - initialStateOfGreatGrandParent->setObjectName("initialStateOfGreatGrandParent"); - greatGrandParent->setInitialState(initialStateOfGreatGrandParent); - - initialStateOfGreatGrandParent->addTransition(new EventTransition(QEvent::User, state)); - - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), true); - QCOMPARE(entryController->property("grandParentEntered").toBool(), false); - QCOMPARE(entryController->property("parentEntered").toBool(), false); - QCOMPARE(entryController->property("stateEntered").toBool(), false); - QCOMPARE(machine.configuration().count(), 2); - QVERIFY(machine.configuration().contains(greatGrandParent)); - QVERIFY(machine.configuration().contains(initialStateOfGreatGrandParent)); - - entryController->setProperty("greatGrandParentEntered", false); - entryController->setProperty("grandParentEntered", false); - entryController->setProperty("parentEntered", false); - entryController->setProperty("stateEntered", false); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), false); - QCOMPARE(entryController->property("grandParentEntered").toBool(), true); - QCOMPARE(entryController->property("parentEntered").toBool(), true); - QCOMPARE(entryController->property("stateEntered").toBool(), true); - QCOMPARE(machine.configuration().count(), 4); - QVERIFY(machine.configuration().contains(greatGrandParent)); - QVERIFY(machine.configuration().contains(grandParent)); - QVERIFY(machine.configuration().contains(parent)); - QVERIFY(machine.configuration().contains(state)); -} - -void tst_QStateMachine::defaultErrorState() -{ - QStateMachine machine; - QVERIFY(machine.errorState() != 0); - - QState *brokenState = new QState(); - brokenState->setObjectName("MyInitialState"); - - machine.addState(brokenState); - machine.setInitialState(brokenState); - - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'MyInitialState'"); - - // initialState has no initial state - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); - QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'MyInitialState'")); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(machine.errorState())); -} - -class CustomErrorState: public QState -{ -public: - CustomErrorState(QStateMachine *machine, QState *parent = 0) - : QState(parent), error(QStateMachine::NoError), m_machine(machine) - { - } - - void onEntry(QEvent *) - { - error = m_machine->error(); - errorString = m_machine->errorString(); - } - - QStateMachine::Error error; - QString errorString; - -private: - QStateMachine *m_machine; -}; - -void tst_QStateMachine::customGlobalErrorState() -{ - QStateMachine machine; - - CustomErrorState *customErrorState = new CustomErrorState(&machine); - customErrorState->setObjectName("customErrorState"); - machine.addState(customErrorState); - machine.setErrorState(customErrorState); - - QState *initialState = new QState(); - initialState->setObjectName("initialState"); - machine.addState(initialState); - machine.setInitialState(initialState); - - QState *brokenState = new QState(); - brokenState->setObjectName("brokenState"); - machine.addState(brokenState); - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(machine.errorState(), customErrorState); - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(initialState)); - - machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(initialState)); - - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(customErrorState)); - QCOMPARE(customErrorState->error, QStateMachine::NoInitialStateError); - QCOMPARE(customErrorState->errorString, QString::fromLatin1("Missing initial state in compound state 'brokenState'")); - QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); - QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'brokenState'")); -} - -void tst_QStateMachine::customLocalErrorStateInBrokenState() -{ - QStateMachine machine; - CustomErrorState *customErrorState = new CustomErrorState(&machine); - machine.addState(customErrorState); - - QState *initialState = new QState(); - initialState->setObjectName("initialState"); - machine.addState(initialState); - machine.setInitialState(initialState); - - QState *brokenState = new QState(); - brokenState->setObjectName("brokenState"); - machine.addState(brokenState); - brokenState->setErrorState(customErrorState); - - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(customErrorState)); - QCOMPARE(customErrorState->error, QStateMachine::NoInitialStateError); -} - -void tst_QStateMachine::customLocalErrorStateInOtherState() -{ - QStateMachine machine; - CustomErrorState *customErrorState = new CustomErrorState(&machine); - machine.addState(customErrorState); - - QState *initialState = new QState(); - initialState->setObjectName("initialState"); - QTest::ignoreMessage(QtWarningMsg, "QState::setErrorState: error state cannot belong to a different state machine"); - initialState->setErrorState(customErrorState); - machine.addState(initialState); - machine.setInitialState(initialState); - - QState *brokenState = new QState(); - brokenState->setObjectName("brokenState"); - - machine.addState(brokenState); - - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); - - QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'brokenState'"); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(machine.errorState())); -} - -void tst_QStateMachine::customLocalErrorStateInParentOfBrokenState() -{ - QStateMachine machine; - CustomErrorState *customErrorState = new CustomErrorState(&machine); - machine.addState(customErrorState); - - QState *initialState = new QState(); - initialState->setObjectName("initialState"); - machine.addState(initialState); - machine.setInitialState(initialState); - - QState *parentOfBrokenState = new QState(); - machine.addState(parentOfBrokenState); - parentOfBrokenState->setObjectName("parentOfBrokenState"); - parentOfBrokenState->setErrorState(customErrorState); - - QState *brokenState = new QState(parentOfBrokenState); - brokenState->setObjectName("brokenState"); - parentOfBrokenState->setInitialState(brokenState); - - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(customErrorState)); -} - -void tst_QStateMachine::customLocalErrorStateOverridesParent() -{ - QStateMachine machine; - CustomErrorState *customErrorStateForParent = new CustomErrorState(&machine); - machine.addState(customErrorStateForParent); - - CustomErrorState *customErrorStateForBrokenState = new CustomErrorState(&machine); - machine.addState(customErrorStateForBrokenState); - - QState *initialState = new QState(); - initialState->setObjectName("initialState"); - machine.addState(initialState); - machine.setInitialState(initialState); - - QState *parentOfBrokenState = new QState(); - machine.addState(parentOfBrokenState); - parentOfBrokenState->setObjectName("parentOfBrokenState"); - parentOfBrokenState->setErrorState(customErrorStateForParent); - - QState *brokenState = new QState(parentOfBrokenState); - brokenState->setObjectName("brokenState"); - brokenState->setErrorState(customErrorStateForBrokenState); - parentOfBrokenState->setInitialState(brokenState); - - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(customErrorStateForBrokenState)); - QCOMPARE(customErrorStateForBrokenState->error, QStateMachine::NoInitialStateError); - QCOMPARE(customErrorStateForParent->error, QStateMachine::NoError); -} - -void tst_QStateMachine::errorStateHasChildren() -{ - QStateMachine machine; - CustomErrorState *customErrorState = new CustomErrorState(&machine); - customErrorState->setObjectName("customErrorState"); - machine.addState(customErrorState); - - machine.setErrorState(customErrorState); - - QState *childOfErrorState = new QState(customErrorState); - childOfErrorState->setObjectName("childOfErrorState"); - customErrorState->setInitialState(childOfErrorState); - - QState *initialState = new QState(); - initialState->setObjectName("initialState"); - machine.addState(initialState); - machine.setInitialState(initialState); - - QState *brokenState = new QState(); - brokenState->setObjectName("brokenState"); - machine.addState(brokenState); - - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 2); - QVERIFY(machine.configuration().contains(customErrorState)); - QVERIFY(machine.configuration().contains(childOfErrorState)); -} - - -void tst_QStateMachine::errorStateHasErrors() -{ - QStateMachine machine; - CustomErrorState *customErrorState = new CustomErrorState(&machine); - customErrorState->setObjectName("customErrorState"); - machine.addState(customErrorState); - - QAbstractState *oldErrorState = machine.errorState(); - machine.setErrorState(customErrorState); - - QState *childOfErrorState = new QState(customErrorState); - childOfErrorState->setObjectName("childOfErrorState"); - - QState *initialState = new QState(); - initialState->setObjectName("initialState"); - machine.addState(initialState); - machine.setInitialState(initialState); - - QState *brokenState = new QState(); - brokenState->setObjectName("brokenState"); - machine.addState(brokenState); - - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); - QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'customErrorState'"); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(oldErrorState)); // Fall back to default - QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); - QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'customErrorState'")); -} - -void tst_QStateMachine::errorStateIsRootState() -{ - QStateMachine machine; - QTest::ignoreMessage(QtWarningMsg, "QStateMachine::setErrorState: root state cannot be error state"); - machine.setErrorState(machine.rootState()); - - QState *initialState = new QState(); - initialState->setObjectName("initialState"); - machine.addState(initialState); - machine.setInitialState(initialState); - - QState *brokenState = new QState(); - brokenState->setObjectName("brokenState"); - machine.addState(brokenState); - - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - initialState->addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), brokenState)); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1))); - QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'brokenState'"); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(machine.errorState())); -} - -void tst_QStateMachine::errorStateEntersParentFirst() -{ - QStateMachine machine; - - QObject *entryController = new QObject(&machine); - entryController->setObjectName("entryController"); - entryController->setProperty("greatGrandParentEntered", false); - entryController->setProperty("grandParentEntered", false); - entryController->setProperty("parentEntered", false); - entryController->setProperty("errorStateEntered", false); - - QState *greatGrandParent = new QState(); - greatGrandParent->setObjectName("greatGrandParent"); - greatGrandParent->assignProperty(entryController, "greatGrandParentEntered", true); - machine.addState(greatGrandParent); - machine.setInitialState(greatGrandParent); - - QState *grandParent = new QState(greatGrandParent); - grandParent->setObjectName("grandParent"); - grandParent->assignProperty(entryController, "grandParentEntered", true); - - QState *parent = new QState(grandParent); - parent->setObjectName("parent"); - parent->assignProperty(entryController, "parentEntered", true); - - QState *errorState = new QState(parent); - errorState->setObjectName("errorState"); - errorState->assignProperty(entryController, "errorStateEntered", true); - machine.setErrorState(errorState); - - QState *initialStateOfGreatGrandParent = new QState(greatGrandParent); - initialStateOfGreatGrandParent->setObjectName("initialStateOfGreatGrandParent"); - greatGrandParent->setInitialState(initialStateOfGreatGrandParent); - - QState *brokenState = new QState(greatGrandParent); - brokenState->setObjectName("brokenState"); - - QState *childState = new QState(brokenState); - childState->setObjectName("childState"); - - initialStateOfGreatGrandParent->addTransition(new EventTransition(QEvent::User, brokenState)); - - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), true); - QCOMPARE(entryController->property("grandParentEntered").toBool(), false); - QCOMPARE(entryController->property("parentEntered").toBool(), false); - QCOMPARE(entryController->property("errorStateEntered").toBool(), false); - QCOMPARE(machine.configuration().count(), 2); - QVERIFY(machine.configuration().contains(greatGrandParent)); - QVERIFY(machine.configuration().contains(initialStateOfGreatGrandParent)); - - entryController->setProperty("greatGrandParentEntered", false); - entryController->setProperty("grandParentEntered", false); - entryController->setProperty("parentEntered", false); - entryController->setProperty("errorStateEntered", false); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(entryController->property("greatGrandParentEntered").toBool(), false); - QCOMPARE(entryController->property("grandParentEntered").toBool(), true); - QCOMPARE(entryController->property("parentEntered").toBool(), true); - QCOMPARE(entryController->property("errorStateEntered").toBool(), true); - QCOMPARE(machine.configuration().count(), 4); - QVERIFY(machine.configuration().contains(greatGrandParent)); - QVERIFY(machine.configuration().contains(grandParent)); - QVERIFY(machine.configuration().contains(parent)); - QVERIFY(machine.configuration().contains(errorState)); -} - -void tst_QStateMachine::customErrorStateIsNull() -{ - QStateMachine machine; - QAbstractState *oldErrorState = machine.errorState(); - machine.rootState()->setErrorState(0); - - QState *initialState = new QState(); - machine.addState(initialState); - machine.setInitialState(initialState); - - QState *brokenState = new QState(); - machine.addState(brokenState); - - new QState(brokenState); - initialState->addTransition(new EventTransition(QEvent::User, brokenState)); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state ''"); - QCoreApplication::processEvents(); - - QCOMPARE(machine.errorState(), reinterpret_cast(0)); - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(oldErrorState)); -} - -void tst_QStateMachine::clearError() -{ - QStateMachine machine; - machine.setErrorState(new QState(machine.rootState())); // avoid warnings - - QState *brokenState = new QState(machine.rootState()); - brokenState->setObjectName("brokenState"); - machine.setInitialState(brokenState); - new QState(brokenState); - - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(machine.error(), QStateMachine::NoInitialStateError); - QCOMPARE(machine.errorString(), QString::fromLatin1("Missing initial state in compound state 'brokenState'")); - - machine.clearError(); - - QCOMPARE(machine.error(), QStateMachine::NoError); - QVERIFY(machine.errorString().isEmpty()); -} - -void tst_QStateMachine::historyStateAsInitialState() -{ - QStateMachine machine; - - QHistoryState *hs = new QHistoryState(machine.rootState()); - machine.setInitialState(hs); - - QState *s1 = new QState(machine.rootState()); - hs->setDefaultState(s1); - - QState *s2 = new QState(machine.rootState()); - - QHistoryState *s2h = new QHistoryState(s2); - s2->setInitialState(s2h); - - QState *s21 = new QState(s2); - s2h->setDefaultState(s21); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s21)); -} - -void tst_QStateMachine::historyStateHasNowhereToGo() -{ - QStateMachine machine; - - QState *initialState = new QState(machine.rootState()); - machine.setInitialState(initialState); - machine.setErrorState(new QState(machine.rootState())); // avoid warnings - - QState *brokenState = new QState(machine.rootState()); - brokenState->setObjectName("brokenState"); - brokenState->setInitialState(new QState(brokenState)); - - QHistoryState *historyState = new QHistoryState(brokenState); - historyState->setObjectName("historyState"); - initialState->addTransition(new EventTransition(QEvent::User, historyState)); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(machine.errorState())); - QCOMPARE(machine.error(), QStateMachine::NoDefaultStateInHistoryStateError); - QCOMPARE(machine.errorString(), QString::fromLatin1("Missing default state in history state 'historyState'")); -} - -void tst_QStateMachine::brokenStateIsNeverEntered() -{ - QStateMachine machine; - - QObject *entryController = new QObject(&machine); - entryController->setProperty("brokenStateEntered", false); - entryController->setProperty("childStateEntered", false); - entryController->setProperty("errorStateEntered", false); - - QState *initialState = new QState(machine.rootState()); - machine.setInitialState(initialState); - - QState *errorState = new QState(machine.rootState()); - errorState->assignProperty(entryController, "errorStateEntered", true); - machine.setErrorState(errorState); - - QState *brokenState = new QState(machine.rootState()); - brokenState->assignProperty(entryController, "brokenStateEntered", true); - brokenState->setObjectName("brokenState"); - - QState *childState = new QState(brokenState); - childState->assignProperty(entryController, "childStateEntered", true); - - initialState->addTransition(new EventTransition(QEvent::User, brokenState)); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(entryController->property("errorStateEntered").toBool(), true); - QCOMPARE(entryController->property("brokenStateEntered").toBool(), false); - QCOMPARE(entryController->property("childStateEntered").toBool(), false); -} - -void tst_QStateMachine::transitionToStateNotInGraph() -{ - QStateMachine machine; - - QState *initialState = new QState(machine.rootState()); - initialState->setObjectName("initialState"); - machine.setInitialState(initialState); - - QState independentState; - independentState.setObjectName("independentState"); - initialState->addTransition(&independentState); - - machine.start(); - QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 'initialState'"); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(qobject_cast(machine.rootState())->errorState())); -} - -void tst_QStateMachine::customErrorStateNotInGraph() -{ - QStateMachine machine; - - QState errorState; - errorState.setObjectName("errorState"); - QTest::ignoreMessage(QtWarningMsg, "QState::setErrorState: error state cannot belong to a different state machine"); - machine.setErrorState(&errorState); - QVERIFY(&errorState != machine.errorState()); - - QState *initialBrokenState = new QState(machine.rootState()); - initialBrokenState->setObjectName("initialBrokenState"); - machine.setInitialState(initialBrokenState); - new QState(initialBrokenState); - - machine.start(); - QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: Missing initial state in compound state 'initialBrokenState'"); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(machine.errorState())); -} - -void tst_QStateMachine::restoreProperties() -{ - QStateMachine machine; - QCOMPARE(machine.globalRestorePolicy(), QStateMachine::DoNotRestoreProperties); - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - - QObject *object = new QObject(&machine); - object->setProperty("a", 1); - object->setProperty("b", 2); - - QState *S1 = new QState(); - S1->setObjectName("S1"); - S1->assignProperty(object, "a", 3); - machine.addState(S1); - - QState *S2 = new QState(); - S2->setObjectName("S2"); - S2->assignProperty(object, "b", 5); - machine.addState(S2); - - QState *S3 = new QState(); - S3->setObjectName("S3"); - machine.addState(S3); - - QFinalState *S4 = new QFinalState(); - machine.addState(S4); - - S1->addTransition(new EventTransition(QEvent::User, S2)); - S2->addTransition(new EventTransition(QEvent::User, S3)); - S3->addTransition(S4); - - machine.setInitialState(S1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("a").toInt(), 3); - QCOMPARE(object->property("b").toInt(), 2); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("a").toInt(), 1); - QCOMPARE(object->property("b").toInt(), 5); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("a").toInt(), 1); - QCOMPARE(object->property("b").toInt(), 2); -} - -void tst_QStateMachine::rootState() -{ - QStateMachine machine; - QVERIFY(machine.rootState() != 0); - QVERIFY(qobject_cast(machine.rootState()) != 0); - QCOMPARE(qobject_cast(machine.rootState())->parentState(), (QState*)0); - QCOMPARE(machine.rootState()->parent(), (QObject*)&machine); - QCOMPARE(machine.rootState()->machine(), &machine); - - QState *s1 = new QState(machine.rootState()); - QCOMPARE(s1->parentState(), machine.rootState()); - - QState *s2 = new QState(); - s2->setParent(&machine); - QCOMPARE(s2->parentState(), machine.rootState()); -} - -void tst_QStateMachine::addAndRemoveState() -{ - QStateMachine machine; - QStatePrivate *root_d = QStatePrivate::get(machine.rootState()); - QCOMPARE(root_d->childStates().size(), 1); // the error state - QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); - - QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: cannot add null state"); - machine.addState(0); - - QState *s1 = new QState(); - QCOMPARE(s1->parentState(), (QState*)0); - QCOMPARE(s1->machine(), (QStateMachine*)0); - machine.addState(s1); - QCOMPARE(s1->machine(), &machine); - QCOMPARE(s1->parentState(), machine.rootState()); - QCOMPARE(root_d->childStates().size(), 2); - QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); - QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s1); - - QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine"); - machine.addState(s1); - - QState *s2 = new QState(); - QCOMPARE(s2->parentState(), (QState*)0); - machine.addState(s2); - QCOMPARE(s2->parentState(), machine.rootState()); - QCOMPARE(root_d->childStates().size(), 3); - QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); - QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s1); - QCOMPARE(root_d->childStates().at(2), (QAbstractState*)s2); - - QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: state has already been added to this machine"); - machine.addState(s2); - - machine.removeState(s1); - QCOMPARE(s1->parentState(), (QState*)0); - QCOMPARE(root_d->childStates().size(), 2); - QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); - QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s2); - - machine.removeState(s2); - QCOMPARE(s2->parentState(), (QState*)0); - QCOMPARE(root_d->childStates().size(), 1); - QCOMPARE(root_d->childStates().at(0), (QAbstractState*)machine.errorState()); - - QTest::ignoreMessage(QtWarningMsg, "QStateMachine::removeState: cannot remove null state"); - machine.removeState(0); - - delete s1; - delete s2; - // ### how to deal with this? - // machine.removeState(machine.errorState()); -} - -void tst_QStateMachine::stateEntryAndExit() -{ - // Two top-level states - { - QStateMachine machine; - - TestState *s1 = new TestState(machine.rootState()); - QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state"); - s1->addTransition((QAbstractState*)0); - QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add null transition"); - s1->addTransition((QAbstractTransition*)0); - QTest::ignoreMessage(QtWarningMsg, "QState::removeTransition: cannot remove null transition"); - s1->removeTransition((QAbstractTransition*)0); - - TestState *s2 = new TestState(machine.rootState()); - QFinalState *s3 = new QFinalState(machine.rootState()); - - TestTransition *t = new TestTransition(s2); - QCOMPARE(t->machine(), (QStateMachine*)0); - QCOMPARE(t->sourceState(), (QState*)0); - QCOMPARE(t->targetState(), s2); - QCOMPARE(t->targetStates().size(), 1); - QCOMPARE(t->targetStates().at(0), s2); - t->setTargetState(0); - QCOMPARE(t->targetState(), (QState*)0); - QVERIFY(t->targetStates().isEmpty()); - t->setTargetState(s2); - QCOMPARE(t->targetState(), s2); - QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::setTargetStates: target state(s) cannot be null"); - t->setTargetStates(QList() << 0); - QCOMPARE(t->targetState(), s2); - t->setTargetStates(QList() << s2); - QCOMPARE(t->targetState(), s2); - QCOMPARE(t->targetStates().size(), 1); - QCOMPARE(t->targetStates().at(0), s2); - QCOMPARE(s1->addTransition(t), (QAbstractTransition*)t); - QCOMPARE(t->sourceState(), s1); - QCOMPARE(t->machine(), &machine); - - { - QAbstractTransition *trans = s2->addTransition(s3); - QVERIFY(trans != 0); - QCOMPARE(trans->sourceState(), (QAbstractState*)s2); - QCOMPARE(trans->targetState(), (QAbstractState*)s3); - { - char warning[256]; - sprintf(warning, "QState::removeTransition: transition %p's source state (%p) is different from this state (%p)", trans, s2, s1); - QTest::ignoreMessage(QtWarningMsg, warning); - s1->removeTransition(trans); - } - s2->removeTransition(trans); - QCOMPARE(trans->sourceState(), (QAbstractState*)0); - QCOMPARE(trans->targetState(), (QAbstractState*)s3); - QCOMPARE(s2->addTransition(trans), trans); - QCOMPARE(trans->sourceState(), (QAbstractState*)s2); - } - - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s1); - QCOMPARE(machine.initialState(), (QAbstractState*)s1); - { - char warning[256]; - sprintf(warning, "QState::setInitialState: state %p is not a child of this state (%p)", machine.rootState(), machine.rootState()); - QTest::ignoreMessage(QtWarningMsg, warning); - machine.setInitialState(machine.rootState()); - QCOMPARE(machine.initialState(), (QAbstractState*)s1); - } - QVERIFY(machine.configuration().isEmpty()); - globalTick = 0; - QVERIFY(!machine.isRunning()); - machine.start(); - - QTRY_COMPARE(startedSpy.count(), 1); - QTRY_COMPARE(finishedSpy.count(), 1); - QTRY_COMPARE(stoppedSpy.count(), 0); - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(s3)); - - // s1 is entered - QCOMPARE(s1->events.count(), 2); - QCOMPARE(s1->events.at(0).first, 0); - QCOMPARE(s1->events.at(0).second, TestState::Entry); - // s1 is exited - QCOMPARE(s1->events.at(1).first, 1); - QCOMPARE(s1->events.at(1).second, TestState::Exit); - // t is triggered - QCOMPARE(t->triggers.count(), 1); - QCOMPARE(t->triggers.at(0), 2); - // s2 is entered - QCOMPARE(s2->events.count(), 2); - QCOMPARE(s2->events.at(0).first, 3); - QCOMPARE(s2->events.at(0).second, TestState::Entry); - // s2 is exited - QCOMPARE(s2->events.at(1).first, 4); - QCOMPARE(s2->events.at(1).second, TestState::Exit); - } - // Two top-level states, one has two child states - { - QStateMachine machine; - - TestState *s1 = new TestState(machine.rootState()); - TestState *s11 = new TestState(s1); - TestState *s12 = new TestState(s1); - TestState *s2 = new TestState(machine.rootState()); - QFinalState *s3 = new QFinalState(machine.rootState()); - s1->setInitialState(s11); - TestTransition *t1 = new TestTransition(s12); - s11->addTransition(t1); - TestTransition *t2 = new TestTransition(s2); - s12->addTransition(t2); - s2->addTransition(s3); - - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s1); - globalTick = 0; - machine.start(); - - QTRY_COMPARE(startedSpy.count(), 1); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(s3)); - - // s1 is entered - QCOMPARE(s1->events.count(), 2); - QCOMPARE(s1->events.at(0).first, 0); - QCOMPARE(s1->events.at(0).second, TestState::Entry); - // s11 is entered - QCOMPARE(s11->events.count(), 2); - QCOMPARE(s11->events.at(0).first, 1); - QCOMPARE(s11->events.at(0).second, TestState::Entry); - // s11 is exited - QCOMPARE(s11->events.at(1).first, 2); - QCOMPARE(s11->events.at(1).second, TestState::Exit); - // t1 is triggered - QCOMPARE(t1->triggers.count(), 1); - QCOMPARE(t1->triggers.at(0), 3); - // s12 is entered - QCOMPARE(s12->events.count(), 2); - QCOMPARE(s12->events.at(0).first, 4); - QCOMPARE(s12->events.at(0).second, TestState::Entry); - // s12 is exited - QCOMPARE(s12->events.at(1).first, 5); - QCOMPARE(s12->events.at(1).second, TestState::Exit); - // s1 is exited - QCOMPARE(s1->events.at(1).first, 6); - QCOMPARE(s1->events.at(1).second, TestState::Exit); - // t2 is triggered - QCOMPARE(t2->triggers.count(), 1); - QCOMPARE(t2->triggers.at(0), 7); - // s2 is entered - QCOMPARE(s2->events.count(), 2); - QCOMPARE(s2->events.at(0).first, 8); - QCOMPARE(s2->events.at(0).second, TestState::Entry); - // s2 is exited - QCOMPARE(s2->events.at(1).first, 9); - QCOMPARE(s2->events.at(1).second, TestState::Exit); - } -} - -void tst_QStateMachine::assignProperty() -{ - QStateMachine machine; - QState *s1 = new QState(machine.rootState()); - - QTest::ignoreMessage(QtWarningMsg, "QState::assignProperty: cannot assign property 'foo' of null object"); - s1->assignProperty(0, "foo", QVariant()); - - s1->assignProperty(s1, "objectName", "s1"); - QFinalState *s2 = new QFinalState(machine.rootState()); - s1->addTransition(s2); - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - QCOMPARE(s1->objectName(), QString::fromLatin1("s1")); - - s1->assignProperty(s1, "objectName", "foo"); - machine.start(); - QCoreApplication::processEvents(); - QCOMPARE(s1->objectName(), QString::fromLatin1("foo")); - - s1->assignProperty(s1, "noSuchProperty", 123); - machine.start(); - QCoreApplication::processEvents(); - QCOMPARE(s1->objectName(), QString::fromLatin1("foo")); - QCOMPARE(s1->dynamicPropertyNames().size(), 1); - QCOMPARE(s1->dynamicPropertyNames().at(0), QByteArray("noSuchProperty")); - - QSignalSpy polishedSpy(s1, SIGNAL(polished())); - machine.start(); - QCoreApplication::processEvents(); - QCOMPARE(polishedSpy.count(), 1); -} - -void tst_QStateMachine::assignPropertyWithAnimation() -{ - // Single animation - { - QStateMachine machine; - QVERIFY(machine.animationsEnabled()); - machine.setAnimationsEnabled(false); - QVERIFY(!machine.animationsEnabled()); - machine.setAnimationsEnabled(true); - QVERIFY(machine.animationsEnabled()); - QObject obj; - obj.setProperty("foo", 321); - obj.setProperty("bar", 654); - QState *s1 = new QState(machine.rootState()); - s1->assignProperty(&obj, "foo", 123); - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(&obj, "foo", 456); - s2->assignProperty(&obj, "bar", 789); - QAbstractTransition *trans = s1->addTransition(s2); - QVERIFY(trans->animations().isEmpty()); - QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::addAnimation: cannot add null animation"); - trans->addAnimation(0); - QPropertyAnimation anim(&obj, "foo"); - anim.setDuration(250); - trans->addAnimation(&anim); - QCOMPARE(trans->animations().size(), 1); - QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim); - QCOMPARE(anim.parent(), (QObject*)0); - QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::removeAnimation: cannot remove null animation"); - trans->removeAnimation(0); - trans->removeAnimation(&anim); - QVERIFY(trans->animations().isEmpty()); - trans->addAnimation(&anim); - QCOMPARE(trans->animations().size(), 1); - QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim); - QFinalState *s3 = new QFinalState(machine.rootState()); - s2->addTransition(s2, SIGNAL(polished()), s3); - - machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(obj.property("foo").toInt(), 456); - QCOMPARE(obj.property("bar").toInt(), 789); - } - // Two animations - { - QStateMachine machine; - QObject obj; - obj.setProperty("foo", 321); - obj.setProperty("bar", 654); - QState *s1 = new QState(machine.rootState()); - s1->assignProperty(&obj, "foo", 123); - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(&obj, "foo", 456); - s2->assignProperty(&obj, "bar", 789); - QAbstractTransition *trans = s1->addTransition(s2); - QPropertyAnimation anim(&obj, "foo"); - anim.setDuration(150); - trans->addAnimation(&anim); - QPropertyAnimation anim2(&obj, "bar"); - anim2.setDuration(150); - trans->addAnimation(&anim2); - QFinalState *s3 = new QFinalState(machine.rootState()); - s2->addTransition(s2, SIGNAL(polished()), s3); - - machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(obj.property("foo").toInt(), 456); - QCOMPARE(obj.property("bar").toInt(), 789); - } - // Animation group - { - QStateMachine machine; - QObject obj; - obj.setProperty("foo", 321); - obj.setProperty("bar", 654); - QState *s1 = new QState(machine.rootState()); - s1->assignProperty(&obj, "foo", 123); - s1->assignProperty(&obj, "bar", 321); - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(&obj, "foo", 456); - s2->assignProperty(&obj, "bar", 654); - s2->assignProperty(&obj, "baz", 789); - QAbstractTransition *trans = s1->addTransition(s2); - QSequentialAnimationGroup group; - group.addAnimation(new QPropertyAnimation(&obj, "foo")); - group.addAnimation(new QPropertyAnimation(&obj, "bar")); - trans->addAnimation(&group); - QFinalState *s3 = new QFinalState(machine.rootState()); - s2->addTransition(s2, SIGNAL(polished()), s3); - - machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(obj.property("foo").toInt(), 456); - QCOMPARE(obj.property("bar").toInt(), 654); - QCOMPARE(obj.property("baz").toInt(), 789); - } - // Nested states - { - QStateMachine machine; - QObject obj; - obj.setProperty("foo", 321); - obj.setProperty("bar", 654); - QState *s1 = new QState(machine.rootState()); - QCOMPARE(s1->childMode(), QState::ExclusiveStates); - s1->setChildMode(QState::ParallelStates); - QCOMPARE(s1->childMode(), QState::ParallelStates); - s1->setChildMode(QState::ExclusiveStates); - QCOMPARE(s1->childMode(), QState::ExclusiveStates); - QCOMPARE(s1->initialState(), (QAbstractState*)0); - s1->setObjectName("s1"); - s1->assignProperty(&obj, "foo", 123); - s1->assignProperty(&obj, "bar", 456); - QState *s2 = new QState(machine.rootState()); - s2->setObjectName("s2"); - s2->assignProperty(&obj, "foo", 321); - QState *s21 = new QState(s2); - s21->setObjectName("s21"); - s21->assignProperty(&obj, "bar", 654); - QState *s22 = new QState(s2); - s22->setObjectName("s22"); - s22->assignProperty(&obj, "bar", 789); - s2->setInitialState(s21); - QCOMPARE(s2->initialState(), (QAbstractState*)s21); - - QAbstractTransition *trans = s1->addTransition(s2); - QPropertyAnimation anim(&obj, "foo"); - anim.setDuration(500); - trans->addAnimation(&anim); - QPropertyAnimation anim2(&obj, "bar"); - anim2.setDuration(250); - trans->addAnimation(&anim2); - - s21->addTransition(s21, SIGNAL(polished()), s22); - - QFinalState *s3 = new QFinalState(machine.rootState()); - s22->addTransition(s2, SIGNAL(polished()), s3); - - machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(obj.property("foo").toInt(), 321); - QCOMPARE(obj.property("bar").toInt(), 789); - } -} - -struct StringEvent : public QEvent -{ -public: - StringEvent(const QString &val) - : QEvent(QEvent::Type(QEvent::User+2)), - value(val) {} - - QString value; -}; - -class StringTransition : public QAbstractTransition -{ -public: - StringTransition(const QString &value, QAbstractState *target) - : QAbstractTransition(QList() << target), m_value(value) {} - -protected: - virtual bool eventTest(QEvent *e) - { - if (e->type() != QEvent::Type(QEvent::User+2)) - return false; - StringEvent *se = static_cast(e); - return (m_value == se->value) && (!m_cond.isValid() || (m_cond.indexIn(m_value) != -1)); - } - virtual void onTransition(QEvent *) {} - -private: - QString m_value; - QRegExp m_cond; -}; - -class StringEventPoster : public QState -{ -public: - StringEventPoster(QStateMachine *machine, const QString &value, QState *parent = 0) - : QState(parent), m_machine(machine), m_value(value), m_delay(0) {} - - void setString(const QString &value) - { m_value = value; } - void setDelay(int delay) - { m_delay = delay; } - -protected: - virtual void onEntry(QEvent *) - { - m_machine->postEvent(new StringEvent(m_value), m_delay); - } - virtual void onExit(QEvent *) {} - -private: - QStateMachine *m_machine; - QString m_value; - int m_delay; -}; - -void tst_QStateMachine::postEvent() -{ - for (int x = 0; x < 2; ++x) { - QStateMachine machine; - { - QEvent e(QEvent::None); - QTest::ignoreMessage(QtWarningMsg, "QStateMachine::postEvent: cannot post event when the state machine is not running"); - machine.postEvent(&e); - } - StringEventPoster *s1 = new StringEventPoster(&machine, "a"); - if (x == 1) - s1->setDelay(100); - QFinalState *s2 = new QFinalState; - s1->addTransition(new StringTransition("a", s2)); - machine.addState(s1); - machine.addState(s2); - machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s2)); - - s1->setString("b"); - QFinalState *s3 = new QFinalState(); - machine.addState(s3); - s1->addTransition(new StringTransition("b", s3)); - finishedSpy.clear(); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s3)); - } -} - -void tst_QStateMachine::stateFinished() -{ - QStateMachine machine; - QState *s1 = new QState(machine.rootState()); - QState *s1_1 = new QState(s1); - QFinalState *s1_2 = new QFinalState(s1); - s1_1->addTransition(s1_2); - s1->setInitialState(s1_1); - QFinalState *s2 = new QFinalState(machine.rootState()); - s1->addTransition(s1, SIGNAL(finished()), s2); - machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s2)); -} - -void tst_QStateMachine::parallelStates() -{ - QStateMachine machine; - - QState *s1 = new QState(QState::ParallelStates); - QCOMPARE(s1->childMode(), QState::ParallelStates); - QState *s1_1 = new QState(s1); - QState *s1_1_1 = new QState(s1_1); - QFinalState *s1_1_f = new QFinalState(s1_1); - s1_1_1->addTransition(s1_1_f); - s1_1->setInitialState(s1_1_1); - QState *s1_2 = new QState(s1); - QState *s1_2_1 = new QState(s1_2); - QFinalState *s1_2_f = new QFinalState(s1_2); - s1_2_1->addTransition(s1_2_f); - s1_2->setInitialState(s1_2_1); - { - char warning[256]; - sprintf(warning, "QState::setInitialState: ignoring attempt to set initial state of parallel state group %p", s1); - QTest::ignoreMessage(QtWarningMsg, warning); - s1->setInitialState(0); - } - machine.addState(s1); - - QFinalState *s2 = new QFinalState(); - machine.addState(s2); - - s1->addTransition(s1, SIGNAL(finished()), s2); - - machine.setInitialState(s1); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s2)); -} - -void tst_QStateMachine::allSourceToTargetConfigurations() -{ - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - s0->setObjectName("s0"); - QState *s1 = new QState(s0); - s1->setObjectName("s1"); - QState *s11 = new QState(s1); - s11->setObjectName("s11"); - QState *s2 = new QState(s0); - s2->setObjectName("s2"); - QState *s21 = new QState(s2); - s21->setObjectName("s21"); - QState *s211 = new QState(s21); - s211->setObjectName("s211"); - QFinalState *f = new QFinalState(machine.rootState()); - f->setObjectName("f"); - - s0->setInitialState(s1); - s1->setInitialState(s11); - s2->setInitialState(s21); - s21->setInitialState(s211); - - s11->addTransition(new StringTransition("g", s211)); - s1->addTransition(new StringTransition("a", s1)); - s1->addTransition(new StringTransition("b", s11)); - s1->addTransition(new StringTransition("c", s2)); - s1->addTransition(new StringTransition("d", s0)); - s1->addTransition(new StringTransition("f", s211)); - s211->addTransition(new StringTransition("d", s21)); - s211->addTransition(new StringTransition("g", s0)); - s211->addTransition(new StringTransition("h", f)); - s21->addTransition(new StringTransition("b", s211)); - s2->addTransition(new StringTransition("c", s1)); - s2->addTransition(new StringTransition("f", s11)); - s0->addTransition(new StringTransition("e", s211)); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new StringEvent("a")); - QCoreApplication::processEvents(); - machine.postEvent(new StringEvent("b")); - QCoreApplication::processEvents(); - machine.postEvent(new StringEvent("c")); - QCoreApplication::processEvents(); - machine.postEvent(new StringEvent("d")); - QCoreApplication::processEvents(); - machine.postEvent(new StringEvent("e")); - QCoreApplication::processEvents(); - machine.postEvent(new StringEvent("f")); - QCoreApplication::processEvents(); - machine.postEvent(new StringEvent("g")); - QCoreApplication::processEvents(); - machine.postEvent(new StringEvent("h")); - QCoreApplication::processEvents(); - - QTRY_COMPARE(finishedSpy.count(), 1); -} - -class SignalEmitter : public QObject -{ -Q_OBJECT - public: - SignalEmitter(QObject *parent = 0) - : QObject(parent) {} - void emitSignalWithNoArg() - { emit signalWithNoArg(); } - void emitSignalWithIntArg(int arg) - { emit signalWithIntArg(arg); } - void emitSignalWithStringArg(const QString &arg) - { emit signalWithStringArg(arg); } -Q_SIGNALS: - void signalWithNoArg(); - void signalWithIntArg(int); - void signalWithStringArg(const QString &); -}; - -class TestSignalTransition : public QSignalTransition -{ -public: - TestSignalTransition(QState *sourceState = 0) - : QSignalTransition(sourceState) {} - TestSignalTransition(QObject *sender, const char *signal, - QAbstractState *target) - : QSignalTransition(sender, signal, QList() << target) {} - QVariantList argumentsReceived() const { - return m_args; - } -protected: - bool eventTest(QEvent *e) { - if (!QSignalTransition::eventTest(e)) - return false; - QSignalEvent *se = static_cast(e); - const_cast(this)->m_args = se->arguments(); - return true; - } -private: - QVariantList m_args; -}; - -void tst_QStateMachine::signalTransitions() -{ - { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: sender cannot be null"); - QCOMPARE(s0->addTransition(0, SIGNAL(noSuchSignal()), 0), (QObject*)0); - - SignalEmitter emitter; - QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: signal cannot be null"); - QCOMPARE(s0->addTransition(&emitter, 0, 0), (QObject*)0); - - QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state"); - QCOMPARE(s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), 0), (QObject*)0); - - QFinalState *s1 = new QFinalState(machine.rootState()); - QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: no such signal SignalEmitter::noSuchSignal()"); - QCOMPARE(s0->addTransition(&emitter, SIGNAL(noSuchSignal()), s1), (QObject*)0); - - { - QSignalTransition *trans = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); - QVERIFY(trans != 0); - QCOMPARE(trans->sourceState(), s0); - QCOMPARE(trans->targetState(), (QAbstractState*)s1); - QCOMPARE(trans->senderObject(), (QObject*)&emitter); - QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); - } - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - emitter.emitSignalWithNoArg(); - - QTRY_COMPARE(finishedSpy.count(), 1); - - emitter.emitSignalWithNoArg(); - } - { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); - SignalEmitter emitter; - TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithIntArg(int)), s1); - s0->addTransition(trans); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - emitter.emitSignalWithIntArg(123); - - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(trans->argumentsReceived().size(), 1); - QCOMPARE(trans->argumentsReceived().at(0).toInt(), 123); - } - { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); - SignalEmitter emitter; - TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s1); - s0->addTransition(trans); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - QString testString = QString::fromLatin1("hello"); - emitter.emitSignalWithStringArg(testString); - - QTRY_COMPARE(finishedSpy.count(), 1); - QCOMPARE(trans->argumentsReceived().size(), 1); - QCOMPARE(trans->argumentsReceived().at(0).toString(), testString); - } - { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); - - TestSignalTransition *trans = new TestSignalTransition(); - QCOMPARE(trans->senderObject(), (QObject*)0); - QCOMPARE(trans->signal(), QByteArray()); - - SignalEmitter emitter; - trans->setSenderObject(&emitter); - QCOMPARE(trans->senderObject(), (QObject*)&emitter); - trans->setSignal(SIGNAL(signalWithNoArg())); - QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); - trans->setTargetState(s1); - s0->addTransition(trans); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - emitter.emitSignalWithNoArg(); - - QTRY_COMPARE(finishedSpy.count(), 1); - } - // Multiple transitions for same (object,signal) - { - QStateMachine machine; - SignalEmitter emitter; - QState *s0 = new QState(machine.rootState()); - QState *s1 = new QState(machine.rootState()); - QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); - QSignalTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s0); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s0)); - - emitter.emitSignalWithNoArg(); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - - s0->removeTransition(t0); - emitter.emitSignalWithNoArg(); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s0)); - - emitter.emitSignalWithNoArg(); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s0)); - - s1->removeTransition(t1); - emitter.emitSignalWithNoArg(); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s0)); - - s0->addTransition(t0); - s1->addTransition(t1); - emitter.emitSignalWithNoArg(); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - } -} - -void tst_QStateMachine::eventTransitions() -{ - QPushButton button; - for (int x = 0; x < 2; ++x) { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); - - QMouseEventTransition *trans; - if (x == 0) { - trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, Qt::LeftButton); - QCOMPARE(trans->targetState(), (QAbstractState*)0); - trans->setTargetState(s1); - } else { - trans = new QMouseEventTransition(&button, QEvent::MouseButtonPress, - Qt::LeftButton, QList() << s1); - } - QCOMPARE(trans->eventType(), QEvent::MouseButtonPress); - QCOMPARE(trans->button(), Qt::LeftButton); - QCOMPARE(trans->targetState(), (QAbstractState*)s1); - s0->addTransition(trans); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - QTest::mousePress(&button, Qt::LeftButton); - QTRY_COMPARE(finishedSpy.count(), 1); - - QTest::mousePress(&button, Qt::LeftButton); - - trans->setEventType(QEvent::MouseButtonRelease); - QCOMPARE(trans->eventType(), QEvent::MouseButtonRelease); - machine.start(); - QCoreApplication::processEvents(); - QTest::mouseRelease(&button, Qt::LeftButton); - QTRY_COMPARE(finishedSpy.count(), 2); - } - for (int x = 0; x < 3; ++x) { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); - - QEventTransition *trans; - if (x == 0) { - trans = new QEventTransition(); - QCOMPARE(trans->eventObject(), (QObject*)0); - QCOMPARE(trans->eventType(), QEvent::None); - trans->setEventObject(&button); - trans->setEventType(QEvent::MouseButtonPress); - trans->setTargetState(s1); - } else if (x == 1) { - trans = new QEventTransition(&button, QEvent::MouseButtonPress); - trans->setTargetState(s1); - } else { - trans = new QEventTransition(&button, QEvent::MouseButtonPress, - QList() << s1); - } - QCOMPARE(trans->eventObject(), (QObject*)&button); - QCOMPARE(trans->eventType(), QEvent::MouseButtonPress); - QCOMPARE(trans->targetState(), (QAbstractState*)s1); - s0->addTransition(trans); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - QTest::mousePress(&button, Qt::LeftButton); - QCoreApplication::processEvents(); - - QTRY_COMPARE(finishedSpy.count(), 1); - } - { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); - - QMouseEventTransition *trans = new QMouseEventTransition(); - QCOMPARE(trans->eventObject(), (QObject*)0); - QCOMPARE(trans->eventType(), QEvent::None); - QCOMPARE(trans->button(), Qt::NoButton); - trans->setEventObject(&button); - trans->setEventType(QEvent::MouseButtonPress); - trans->setButton(Qt::LeftButton); - trans->setTargetState(s1); - s0->addTransition(trans); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - QTest::mousePress(&button, Qt::LeftButton); - QCoreApplication::processEvents(); - - QTRY_COMPARE(finishedSpy.count(), 1); - } - - { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); - - QKeyEventTransition *trans = new QKeyEventTransition(&button, QEvent::KeyPress, Qt::Key_A); - QCOMPARE(trans->eventType(), QEvent::KeyPress); - QCOMPARE(trans->key(), (int)Qt::Key_A); - trans->setTargetState(s1); - s0->addTransition(trans); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - QTest::keyPress(&button, Qt::Key_A); - QCoreApplication::processEvents(); - - QTRY_COMPARE(finishedSpy.count(), 1); - } - { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); - - QKeyEventTransition *trans = new QKeyEventTransition(); - QCOMPARE(trans->eventObject(), (QObject*)0); - QCOMPARE(trans->eventType(), QEvent::None); - QCOMPARE(trans->key(), 0); - trans->setEventObject(&button); - trans->setEventType(QEvent::KeyPress); - trans->setKey(Qt::Key_A); - trans->setTargetState(s1); - s0->addTransition(trans); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - - QTest::keyPress(&button, Qt::Key_A); - QCoreApplication::processEvents(); - - QTRY_COMPARE(finishedSpy.count(), 1); - } - // Multiple transitions for same (object,event) - { - QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QState *s1 = new QState(machine.rootState()); - QEventTransition *t0 = new QEventTransition(&button, QEvent::MouseButtonPress); - t0->setTargetState(s1); - s0->addTransition(t0); - QEventTransition *t1 = new QEventTransition(&button, QEvent::MouseButtonPress); - t1->setTargetState(s0); - s1->addTransition(t1); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.setInitialState(s0); - machine.start(); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s0)); - - QTest::mousePress(&button, Qt::LeftButton); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - - s0->removeTransition(t0); - QTest::mousePress(&button, Qt::LeftButton); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s0)); - - QTest::mousePress(&button, Qt::LeftButton); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s0)); - - s1->removeTransition(t1); - QTest::mousePress(&button, Qt::LeftButton); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s0)); - - s0->addTransition(t0); - s1->addTransition(t1); - QTest::mousePress(&button, Qt::LeftButton); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - } -} - -void tst_QStateMachine::historyStates() -{ - for (int x = 0; x < 2; ++x) { - QStateMachine machine; - QState *root = machine.rootState(); - QState *s0 = new QState(root); - QState *s00 = new QState(s0); - QState *s01 = new QState(s0); - QHistoryState *s0h; - if (x == 0) { - s0h = new QHistoryState(s0); - QCOMPARE(s0h->historyType(), QHistoryState::ShallowHistory); - s0h->setHistoryType(QHistoryState::DeepHistory); - } else { - s0h = new QHistoryState(QHistoryState::DeepHistory, s0); - } - QCOMPARE(s0h->historyType(), QHistoryState::DeepHistory); - s0h->setHistoryType(QHistoryState::ShallowHistory); - QCOMPARE(s0h->historyType(), QHistoryState::ShallowHistory); - QCOMPARE(s0h->defaultState(), (QAbstractState*)0); - s0h->setDefaultState(s00); - QCOMPARE(s0h->defaultState(), (QAbstractState*)s00); - char warning[256]; - sprintf(warning, "QHistoryState::setDefaultState: state %p does not belong to this history state's group (%p)", s0, s0); - QTest::ignoreMessage(QtWarningMsg, warning); - s0h->setDefaultState(s0); - QState *s1 = new QState(root); - QFinalState *s2 = new QFinalState(root); - - s00->addTransition(new StringTransition("a", s01)); - s0->addTransition(new StringTransition("b", s1)); - s1->addTransition(new StringTransition("c", s0h)); - s0->addTransition(new StringTransition("d", s2)); - - root->setInitialState(s0); - s0->setInitialState(s00); - - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s0)); - QVERIFY(machine.configuration().contains(s00)); - - machine.postEvent(new StringEvent("a")); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s0)); - QVERIFY(machine.configuration().contains(s01)); - - machine.postEvent(new StringEvent("b")); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - - machine.postEvent(new StringEvent("c")); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s0)); - QVERIFY(machine.configuration().contains(s01)); - - machine.postEvent(new StringEvent("d")); - QCoreApplication::processEvents(); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s2)); - - QTRY_COMPARE(finishedSpy.count(), 1); - } -} - -void tst_QStateMachine::startAndStop() -{ - QStateMachine machine; - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - QVERIFY(!machine.isRunning()); - QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start: No initial state set for machine. Refusing to start."); - machine.start(); - QCOMPARE(startedSpy.count(), 0); - QCOMPARE(stoppedSpy.count(), 0); - QCOMPARE(finishedSpy.count(), 0); - QVERIFY(!machine.isRunning()); - machine.stop(); - QCOMPARE(startedSpy.count(), 0); - QCOMPARE(stoppedSpy.count(), 0); - QCOMPARE(finishedSpy.count(), 0); - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - machine.start(); - QTRY_COMPARE(machine.isRunning(), true); - QTRY_COMPARE(startedSpy.count(), 1); - QCOMPARE(stoppedSpy.count(), 0); - QCOMPARE(finishedSpy.count(), 0); - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(s1)); - - machine.stop(); - QTRY_COMPARE(machine.isRunning(), false); - QTRY_COMPARE(stoppedSpy.count(), 1); - QCOMPARE(startedSpy.count(), 1); - QCOMPARE(finishedSpy.count(), 0); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(s1)); -} - -void tst_QStateMachine::targetStateWithNoParent() -{ - QStateMachine machine; - QState *s1 = new QState(machine.rootState()); - s1->setObjectName("s1"); - QState s2; - s1->addTransition(&s2); - machine.setInitialState(s1); - QSignalSpy startedSpy(&machine, SIGNAL(started())); - QSignalSpy stoppedSpy(&machine, SIGNAL(stopped())); - QSignalSpy finishedSpy(&machine, SIGNAL(finished())); - machine.start(); - QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 's1'"); - QTRY_COMPARE(machine.isRunning(), true); - QTRY_COMPARE(startedSpy.count(), 1); - QCOMPARE(stoppedSpy.count(), 0); - QCOMPARE(finishedSpy.count(), 0); - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(machine.errorState())); - QCOMPARE(machine.error(), QStateMachine::NoCommonAncestorForTransitionError); -} - -void tst_QStateMachine::targetStateDeleted() -{ - QStateMachine machine; - QState *s1 = new QState(machine.rootState()); - s1->setObjectName("s1"); - QState *s2 = new QState(machine.rootState()); - QAbstractTransition *trans = s1->addTransition(s2); - delete s2; - QCOMPARE(trans->targetState(), (QAbstractState*)0); - QVERIFY(trans->targetStates().isEmpty()); -} - -void tst_QStateMachine::defaultGlobalRestorePolicy() -{ - QStateMachine machine; - - QObject *propertyHolder = new QObject(&machine); - propertyHolder->setProperty("a", 1); - propertyHolder->setProperty("b", 2); - - QState *s1 = new QState(machine.rootState()); - s1->assignProperty(propertyHolder, "a", 3); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(propertyHolder, "b", 4); - - QState *s3 = new QState(machine.rootState()); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - s2->addTransition(new EventTransition(QEvent::User, s3)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 2); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 4); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 4); -} - -/* -void tst_QStateMachine::restorePolicyNotInherited() -{ - QStateMachine machine; - - QObject *propertyHolder = new QObject(); - propertyHolder->setProperty("a", 1); - propertyHolder->setProperty("b", 2); - - QState *parentState = new QState(machine.rootState()); - parentState->setObjectName("parentState"); - parentState->setRestorePolicy(QState::RestoreProperties); - - QState *s1 = new QState(parentState); - s1->setObjectName("s1"); - s1->assignProperty(propertyHolder, "a", 3); - parentState->setInitialState(s1); - - QState *s2 = new QState(parentState); - s2->setObjectName("s2"); - s2->assignProperty(propertyHolder, "b", 4); - - QState *s3 = new QState(parentState); - s3->setObjectName("s3"); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - s2->addTransition(new EventTransition(QEvent::User, s3)); - - machine.setInitialState(parentState); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 2); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 4); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 4); - -}*/ - -void tst_QStateMachine::globalRestorePolicySetToDoNotRestore() -{ - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::DoNotRestoreProperties); - - QObject *propertyHolder = new QObject(&machine); - propertyHolder->setProperty("a", 1); - propertyHolder->setProperty("b", 2); - - QState *s1 = new QState(machine.rootState()); - s1->assignProperty(propertyHolder, "a", 3); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(propertyHolder, "b", 4); - - QState *s3 = new QState(machine.rootState()); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - s2->addTransition(new EventTransition(QEvent::User, s3)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 2); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 4); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 4); -} - -/* -void tst_QStateMachine::setRestorePolicyToDoNotRestore() -{ - QObject *object = new QObject(); - object->setProperty("a", 1); - object->setProperty("b", 2); - - QStateMachine machine; - - QState *S1 = new QState(); - S1->setObjectName("S1"); - S1->assignProperty(object, "a", 3); - S1->setRestorePolicy(QState::DoNotRestoreProperties); - machine.addState(S1); - - QState *S2 = new QState(); - S2->setObjectName("S2"); - S2->assignProperty(object, "b", 5); - S2->setRestorePolicy(QState::DoNotRestoreProperties); - machine.addState(S2); - - QState *S3 = new QState(); - S3->setObjectName("S3"); - S3->setRestorePolicy(QState::DoNotRestoreProperties); - machine.addState(S3); - - QFinalState *S4 = new QFinalState(); - machine.addState(S4); - - S1->addTransition(new EventTransition(QEvent::User, S2)); - S2->addTransition(new EventTransition(QEvent::User, S3)); - S3->addTransition(S4); - - machine.setInitialState(S1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("a").toInt(), 3); - QCOMPARE(object->property("b").toInt(), 2); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("a").toInt(), 3); - QCOMPARE(object->property("b").toInt(), 5); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(object->property("a").toInt(), 3); - QCOMPARE(object->property("b").toInt(), 5); -} - -void tst_QStateMachine::setGlobalRestorePolicyToGlobalRestore() -{ - s_countWarnings = false; - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::GlobalRestorePolicy); - - QCOMPARE(machine.globalRestorePolicy(), QStateMachine::DoNotRestoreProperties); - QCOMPARE(s_msgType, QtWarningMsg); - - s_msgType = QtDebugMsg; - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - machine.setGlobalRestorePolicy(QStateMachine::GlobalRestorePolicy); - - QCOMPARE(machine.globalRestorePolicy(), QStateMachine::RestoreProperties); - QCOMPARE(s_msgType, QtWarningMsg); -} - - -void tst_QStateMachine::restorePolicyOnChildState() -{ - QStateMachine machine; - - QObject *propertyHolder = new QObject(); - propertyHolder->setProperty("a", 1); - propertyHolder->setProperty("b", 2); - - QState *parentState = new QState(machine.rootState()); - parentState->setObjectName("parentState"); - - QState *s1 = new QState(parentState); - s1->setRestorePolicy(QState::RestoreProperties); - s1->setObjectName("s1"); - s1->assignProperty(propertyHolder, "a", 3); - parentState->setInitialState(s1); - - QState *s2 = new QState(parentState); - s2->setRestorePolicy(QState::RestoreProperties); - s2->setObjectName("s2"); - s2->assignProperty(propertyHolder, "b", 4); - - QState *s3 = new QState(parentState); - s3->setRestorePolicy(QState::RestoreProperties); - s3->setObjectName("s3"); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - s2->addTransition(new EventTransition(QEvent::User, s3)); - - machine.setInitialState(parentState); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 2); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 1); - QCOMPARE(propertyHolder->property("b").toInt(), 4); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 1); - QCOMPARE(propertyHolder->property("b").toInt(), 2); -} -*/ - -void tst_QStateMachine::globalRestorePolicySetToRestore() -{ - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - - QObject *propertyHolder = new QObject(&machine); - propertyHolder->setProperty("a", 1); - propertyHolder->setProperty("b", 2); - - QState *s1 = new QState(machine.rootState()); - s1->assignProperty(propertyHolder, "a", 3); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(propertyHolder, "b", 4); - - QState *s3 = new QState(machine.rootState()); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - s2->addTransition(new EventTransition(QEvent::User, s3)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 3); - QCOMPARE(propertyHolder->property("b").toInt(), 2); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 1); - QCOMPARE(propertyHolder->property("b").toInt(), 4); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("a").toInt(), 1); - QCOMPARE(propertyHolder->property("b").toInt(), 2); -} - -/* -void tst_QStateMachine::mixedRestoreProperties() -{ - QStateMachine machine; - - QObject *propertyHolder = new QObject(); - propertyHolder->setProperty("a", 1); - - QState *s1 = new QState(machine.rootState()); - s1->setRestorePolicy(QState::RestoreProperties); - s1->assignProperty(propertyHolder, "a", 3); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(propertyHolder, "a", 4); - - QState *s3 = new QState(machine.rootState()); - - QState *s4 = new QState(machine.rootState()); - s4->assignProperty(propertyHolder, "a", 5); - - QState *s5 = new QState(machine.rootState()); - s5->setRestorePolicy(QState::RestoreProperties); - s5->assignProperty(propertyHolder, "a", 6); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - s2->addTransition(new EventTransition(QEvent::User, s3)); - s3->addTransition(new EventTransition(QEvent::User, s4)); - s4->addTransition(new EventTransition(QEvent::User, s5)); - s5->addTransition(new EventTransition(QEvent::User, s3)); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - // Enter s1, save current - QCOMPARE(propertyHolder->property("a").toInt(), 3); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - // Enter s2, restorePolicy == DoNotRestore, so restore all properties - QCOMPARE(propertyHolder->property("a").toInt(), 4); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - // Enter s3 - QCOMPARE(propertyHolder->property("a").toInt(), 4); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - // Enter s4 - QCOMPARE(propertyHolder->property("a").toInt(), 5); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - // Enter s5, save current - QCOMPARE(propertyHolder->property("a").toInt(), 6); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - // Enter s3, restore - QCOMPARE(propertyHolder->property("a").toInt(), 5); -} -*/ - -void tst_QStateMachine::transitionWithParent() -{ - QStateMachine machine; - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); - EventTransition *trans = new EventTransition(QEvent::User, s2, s1); - QCOMPARE(trans->sourceState(), s1); - QCOMPARE(trans->targetState(), (QAbstractState*)s2); - QCOMPARE(trans->targetStates().size(), 1); - QCOMPARE(trans->targetStates().at(0), (QAbstractState*)s2); -} - -void tst_QStateMachine::simpleAnimation() -{ - QStateMachine machine; - - QObject *object = new QObject(&machine); - object->setProperty("fooBar", 1.0); - - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "fooBar", 2.0); - - EventTransition *et = new EventTransition(QEvent::User, s2); - QPropertyAnimation *animation = new QPropertyAnimation(object, "fooBar", s2); - et->addAnimation(animation); - s1->addTransition(et); - - QState *s3 = new QState(machine.rootState()); - s2->addTransition(animation, SIGNAL(finished()), s3); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("fooBar").toDouble(), 2.0); -} - -class SlotCalledCounter: public QObject -{ - Q_OBJECT -public: - SlotCalledCounter() : counter(0) {} - - int counter; - -public slots: - void slot() { counter++; } -}; - -void tst_QStateMachine::twoAnimations() -{ - QStateMachine machine; - - QObject *object = new QObject(&machine); - object->setProperty("foo", 1.0); - object->setProperty("bar", 3.0); - - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - s2->assignProperty(object, "bar", 10.0); - - QPropertyAnimation *animationFoo = new QPropertyAnimation(object, "foo", s2); - QPropertyAnimation *animationBar = new QPropertyAnimation(object, "bar", s2); - animationBar->setDuration(900); - - SlotCalledCounter counter; - connect(animationFoo, SIGNAL(finished()), &counter, SLOT(slot())); - connect(animationBar, SIGNAL(finished()), &counter, SLOT(slot())); - - EventTransition *et = new EventTransition(QEvent::User, s2); - et->addAnimation(animationFoo); - et->addAnimation(animationBar); - s1->addTransition(et); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - s2->addTransition(s2, SIGNAL(polished()), s3); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("foo").toDouble(), 2.0); - QCOMPARE(object->property("bar").toDouble(), 10.0); - - QCOMPARE(counter.counter, 2); -} - -void tst_QStateMachine::twoAnimatedTransitions() -{ - QStateMachine machine; - - QObject *object = new QObject(&machine); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 5.0); - QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); - s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - s2->addTransition(fooAnimation, SIGNAL(finished()), s3); - - QState *s4 = new QState(machine.rootState()); - s4->assignProperty(object, "foo", 2.0); - QPropertyAnimation *fooAnimation2 = new QPropertyAnimation(object, "foo", s4); - s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation2); - - QState *s5 = new QState(machine.rootState()); - QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit())); - s4->addTransition(fooAnimation2, SIGNAL(finished()), s5); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("foo").toDouble(), 5.0); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s5)); - QCOMPARE(object->property("foo").toDouble(), 2.0); -} - -void tst_QStateMachine::playAnimationTwice() -{ - QStateMachine machine; - - QObject *object = new QObject(&machine); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 5.0); - QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); - s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - s2->addTransition(fooAnimation, SIGNAL(finished()), s3); - - QState *s4 = new QState(machine.rootState()); - s4->assignProperty(object, "foo", 2.0); - s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation); - - QState *s5 = new QState(machine.rootState()); - QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit())); - s4->addTransition(fooAnimation, SIGNAL(finished()), s5); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("foo").toDouble(), 5.0); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s5)); - QCOMPARE(object->property("foo").toDouble(), 2.0); -} - -void tst_QStateMachine::nestedTargetStateForAnimation() -{ - QStateMachine machine; - - QObject *object = new QObject(&machine); - object->setProperty("foo", 1.0); - object->setProperty("bar", 3.0); - - SlotCalledCounter counter; - - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); - - s2->assignProperty(object, "foo", 2.0); - - QState *s2Child = new QState(s2); - s2Child->assignProperty(object, "bar", 10.0); - s2->setInitialState(s2Child); - - QState *s2Child2 = new QState(s2); - s2Child2->assignProperty(object, "bar", 11.0); - QAbstractTransition *at = s2Child->addTransition(new EventTransition(QEvent::User, s2Child2)); - - QPropertyAnimation *animation = new QPropertyAnimation(object, "bar", s2); - animation->setDuration(2000); - connect(animation, SIGNAL(finished()), &counter, SLOT(slot())); - at->addAnimation(animation); - - at = s1->addTransition(new EventTransition(QEvent::User, s2)); - - animation = new QPropertyAnimation(object, "foo", s2); - connect(animation, SIGNAL(finished()), &counter, SLOT(slot())); - at->addAnimation(animation); - - animation = new QPropertyAnimation(object, "bar", s2); - connect(animation, SIGNAL(finished()), &counter, SLOT(slot())); - at->addAnimation(animation); - - QState *s3 = new QState(machine.rootState()); - s2->addTransition(s2Child, SIGNAL(polished()), s3); - - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - machine.postEvent(new QEvent(QEvent::User)); - - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("foo").toDouble(), 2.0); - QCOMPARE(object->property("bar").toDouble(), 10.0); - QCOMPARE(counter.counter, 2); -} - -void tst_QStateMachine::animatedGlobalRestoreProperty() -{ - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - - QObject *object = new QObject(&machine); - object->setProperty("foo", 1.0); - - SlotCalledCounter counter; - - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - - QState *s4 = new QState(machine.rootState()); - QObject::connect(s4, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); - QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", s2); - connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); - at->addAnimation(pa); - - at = s2->addTransition(pa, SIGNAL(finished()), s3); - pa = new QPropertyAnimation(object, "foo", s3); - connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); - at->addAnimation(pa); - - at = s3->addTransition(pa, SIGNAL(finished()), s4); - pa = new QPropertyAnimation(object, "foo", s4); - connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); - at->addAnimation(pa); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s4)); - QCOMPARE(object->property("foo").toDouble(), 1.0); - QCOMPARE(counter.counter, 2); -} - -void tst_QStateMachine::specificTargetValueOfAnimation() -{ - QStateMachine machine; - - QObject *object = new QObject(&machine); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QPropertyAnimation *anim = new QPropertyAnimation(object, "foo"); - anim->setEndValue(10.0); - s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(anim); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - s2->addTransition(anim, SIGNAL(finished()), s3); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("foo").toDouble(), 2.0); - QCOMPARE(anim->endValue().toDouble(), 10.0); -} - -void tst_QStateMachine::addDefaultAnimation() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); - machine.addDefaultAnimation(pa); - s2->addTransition(pa, SIGNAL(finished()), s3); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("foo").toDouble(), 2.0); -} - -void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation() -{ - QStateMachine machine; - - QObject *object = new QObject(&machine); - object->setProperty("foo", 1.0); - object->setProperty("bar", 2.0); - - SlotCalledCounter counter; - - QState *s1 = new QState(machine.rootState()); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); - connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); - machine.addDefaultAnimation(pa); - s2->addTransition(pa, SIGNAL(finished()), s3); - - pa = new QPropertyAnimation(object, "bar", &machine); - connect(pa, SIGNAL(finished()), &counter, SLOT(slot())); - machine.addDefaultAnimation(pa); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("foo").toDouble(), 2.0); - QCOMPARE(counter.counter, 1); -} - -void tst_QStateMachine::removeDefaultAnimation() -{ - QStateMachine machine; - - QObject propertyHolder; - propertyHolder.setProperty("foo", 0); - - QCOMPARE(machine.defaultAnimations().size(), 0); - - QPropertyAnimation *anim = new QPropertyAnimation(&propertyHolder, "foo"); - - machine.addDefaultAnimation(anim); - - QCOMPARE(machine.defaultAnimations().size(), 1); - QVERIFY(machine.defaultAnimations().contains(anim)); - - machine.removeDefaultAnimation(anim); - - QCOMPARE(machine.defaultAnimations().size(), 0); - - machine.addDefaultAnimation(anim); - - QPropertyAnimation *anim2 = new QPropertyAnimation(&propertyHolder, "foo"); - machine.addDefaultAnimation(anim2); - - QCOMPARE(machine.defaultAnimations().size(), 2); - QVERIFY(machine.defaultAnimations().contains(anim)); - QVERIFY(machine.defaultAnimations().contains(anim2)); - - machine.removeDefaultAnimation(anim); - - QCOMPARE(machine.defaultAnimations().size(), 1); - QVERIFY(machine.defaultAnimations().contains(anim2)); - - machine.removeDefaultAnimation(anim2); - QCOMPARE(machine.defaultAnimations().size(), 0); -} - -void tst_QStateMachine::overrideDefaultAnimationWithSpecific() -{ - QStateMachine machine; - - QObject *object = new QObject(&machine); - object->setProperty("foo", 1.0); - - SlotCalledCounter counter; - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); - connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); - s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); - connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - machine.addDefaultAnimation(defaultAnimation); - at->addAnimation(moreSpecificAnimation); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(counter.counter, 2); // specific animation started and stopped -} - -/* -void tst_QStateMachine::addDefaultAnimationForSource() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); - machine.addDefaultAnimationForSourceState(s1, pa); - s2->addTransition(pa, SIGNAL(finished()), s3); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("foo").toDouble(), 2.0); -} - -void tst_QStateMachine::addDefaultAnimationForTarget() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - QState *s1 = new QState(machine.rootState()); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *pa = new QPropertyAnimation(object, "foo", &machine); - machine.addDefaultAnimationForTargetState(s2, pa); - s2->addTransition(pa, SIGNAL(finished()), s3); - - machine.setInitialState(s1); - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(object->property("foo").toDouble(), 2.0); -} - -void tst_QStateMachine::removeDefaultAnimationForSource() -{ - QStateMachine machine; - - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); - - QPropertyAnimation *anim = new QPropertyAnimation(this, "foo"); - - machine.addDefaultAnimationForSourceState(machine.rootState(), anim); - - QCOMPARE(machine.defaultAnimations().size(), 0); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); - - machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); - - QCOMPARE(machine.defaultAnimations().size(), 0); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); - - machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); - - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); - - machine.addDefaultAnimationForSourceState(machine.rootState(), anim); - - QPropertyAnimation *anim2 = new QPropertyAnimation(this, "foo"); - machine.addDefaultAnimationForSourceState(machine.rootState(), anim2); - - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 2); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim2)); - - machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); - - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim2)); - - machine.removeDefaultAnimationForSourceState(machine.rootState(), anim2); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); -} - -void tst_QStateMachine::removeDefaultAnimationForTarget() -{ - QStateMachine machine; - - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); - - QPropertyAnimation *anim = new QPropertyAnimation(this, "foo"); - - machine.addDefaultAnimationForTargetState(machine.rootState(), anim); - - QCOMPARE(machine.defaultAnimations().size(), 0); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); - - machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); - - QCOMPARE(machine.defaultAnimations().size(), 0); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); - - machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); - - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); - - machine.addDefaultAnimationForTargetState(machine.rootState(), anim); - - QPropertyAnimation *anim2 = new QPropertyAnimation(this, "foo"); - machine.addDefaultAnimationForTargetState(machine.rootState(), anim2); - - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 2); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim2)); - - machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); - - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim2)); - - machine.removeDefaultAnimationForTargetState(machine.rootState(), anim2); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); -} - -void tst_QStateMachine::overrideDefaultAnimationWithSource() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - SlotCalledCounter counter; - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); - connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); - s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); - connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - machine.addDefaultAnimation(defaultAnimation); - machine.addDefaultAnimationForSourceState(s1, moreSpecificAnimation); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(counter.counter, 2); // specific animation started and stopped -} - -void tst_QStateMachine::overrideDefaultAnimationWithTarget() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - SlotCalledCounter counter; - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); - connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); - s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); - connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - machine.addDefaultAnimation(defaultAnimation); - machine.addDefaultAnimationForTargetState(s2, moreSpecificAnimation); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(counter.counter, 2); // specific animation started and stopped - -} - -void tst_QStateMachine::overrideDefaultSourceAnimationWithSpecific() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - SlotCalledCounter counter; - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); - connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); - s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); - connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - machine.addDefaultAnimationForSourceState(s1, defaultAnimation); - at->addAnimation(moreSpecificAnimation); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(counter.counter, 2); // specific animation started and stopped -} - -void tst_QStateMachine::overrideDefaultTargetAnimationWithSpecific() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - SlotCalledCounter counter; - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); - connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); - s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); - connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - machine.addDefaultAnimationForTargetState(s2, defaultAnimation); - at->addAnimation(moreSpecificAnimation); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(counter.counter, 2); // specific animation started and stopped -} - -void tst_QStateMachine::overrideDefaultTargetAnimationWithSource() -{ - QStateMachine machine; - - QObject *object = new QObject(); - object->setProperty("foo", 1.0); - - SlotCalledCounter counter; - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(object, "foo", 2.0); - - QState *s3 = new QState(machine.rootState()); - QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - - QPropertyAnimation *defaultAnimation = new QPropertyAnimation(object, "foo"); - connect(defaultAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - QPropertyAnimation *moreSpecificAnimation = new QPropertyAnimation(object, "foo"); - s2->addTransition(moreSpecificAnimation, SIGNAL(finished()), s3); - connect(moreSpecificAnimation, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)), &counter, SLOT(slot())); - - machine.addDefaultAnimationForTargetState(s2, defaultAnimation); - machine.addDefaultAnimationForSourceState(s1, moreSpecificAnimation); - - machine.start(); - QCoreApplication::processEvents(); - - machine.postEvent(new QEvent(QEvent::User)); - QCOREAPPLICATION_EXEC(5000); - - QVERIFY(machine.configuration().contains(s3)); - QCOMPARE(counter.counter, 2); // specific animation started and stopped -} - -*/ - -void tst_QStateMachine::parallelStateAssignmentsDone() -{ - QStateMachine machine; - - QObject *propertyHolder = new QObject(&machine); - propertyHolder->setProperty("foo", 123); - propertyHolder->setProperty("bar", 456); - propertyHolder->setProperty("zoot", 789); - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - - QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); - parallelState->assignProperty(propertyHolder, "foo", 321); - - QState *s2 = new QState(parallelState); - s2->assignProperty(propertyHolder, "bar", 654); - - QState *s3 = new QState(parallelState); - s3->assignProperty(propertyHolder, "zoot", 987); - - s1->addTransition(new EventTransition(QEvent::User, parallelState)); - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("foo").toInt(), 123); - QCOMPARE(propertyHolder->property("bar").toInt(), 456); - QCOMPARE(propertyHolder->property("zoot").toInt(), 789); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(propertyHolder->property("foo").toInt(), 321); - QCOMPARE(propertyHolder->property("bar").toInt(), 654); - QCOMPARE(propertyHolder->property("zoot").toInt(), 987); -} - -void tst_QStateMachine::transitionsFromParallelStateWithNoChildren() -{ - QStateMachine machine; - - QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); - machine.setInitialState(parallelState); - - QState *s1 = new QState(machine.rootState()); - parallelState->addTransition(new EventTransition(QEvent::User, s1)); - - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(1, machine.configuration().size()); - QVERIFY(machine.configuration().contains(parallelState)); - - machine.postEvent(new QEvent(QEvent::User)); - - QCoreApplication::processEvents(); - - QCOMPARE(1, machine.configuration().size()); - QVERIFY(machine.configuration().contains(s1)); -} - -void tst_QStateMachine::parallelStateTransition() -{ - QStateMachine machine; - - QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); - machine.setInitialState(parallelState); - - QState *s1 = new QState(parallelState); - QState *s2 = new QState(parallelState); - - QState *s1InitialChild = new QState(s1); - s1->setInitialState(s1InitialChild); - - QState *s2InitialChild = new QState(s2); - s2->setInitialState(s2InitialChild); - - QState *s1OtherChild = new QState(s1); - - s1->addTransition(new EventTransition(QEvent::User, s1OtherChild)); - - machine.start(); - QCoreApplication::processEvents(); - - QVERIFY(machine.configuration().contains(parallelState)); - QVERIFY(machine.configuration().contains(s1)); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s1InitialChild)); - QVERIFY(machine.configuration().contains(s2InitialChild)); - QCOMPARE(machine.configuration().size(), 5); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QVERIFY(machine.configuration().contains(parallelState)); - - QVERIFY(machine.configuration().contains(s1)); - - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s1OtherChild)); - QVERIFY(machine.configuration().contains(s2InitialChild)); - QCOMPARE(machine.configuration().size(), 5); - -} - -void tst_QStateMachine::nestedRestoreProperties() -{ - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - - QObject *propertyHolder = new QObject(&machine); - propertyHolder->setProperty("foo", 1); - propertyHolder->setProperty("bar", 2); - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(propertyHolder, "foo", 3); - - QState *s21 = new QState(s2); - s21->assignProperty(propertyHolder, "bar", 4); - s2->setInitialState(s21); - - QState *s22 = new QState(s2); - s22->assignProperty(propertyHolder, "bar", 5); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - s21->addTransition(new EventTransition(QEvent::User, s22)); - - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - QCOMPARE(propertyHolder->property("foo").toInt(), 1); - QCOMPARE(propertyHolder->property("bar").toInt(), 2); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s21)); - QCOMPARE(propertyHolder->property("foo").toInt(), 3); - QCOMPARE(propertyHolder->property("bar").toInt(), 4); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s22)); - QCOMPARE(propertyHolder->property("foo").toInt(), 3); - QCOMPARE(propertyHolder->property("bar").toInt(), 5); -} - -void tst_QStateMachine::nestedRestoreProperties2() -{ - QStateMachine machine; - machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - - QObject *propertyHolder = new QObject(&machine); - propertyHolder->setProperty("foo", 1); - propertyHolder->setProperty("bar", 2); - - QState *s1 = new QState(machine.rootState()); - machine.setInitialState(s1); - - QState *s2 = new QState(machine.rootState()); - s2->assignProperty(propertyHolder, "foo", 3); - - QState *s21 = new QState(s2); - s21->assignProperty(propertyHolder, "bar", 4); - s2->setInitialState(s21); - - QState *s22 = new QState(s2); - s22->assignProperty(propertyHolder, "foo", 6); - s22->assignProperty(propertyHolder, "bar", 5); - - s1->addTransition(new EventTransition(QEvent::User, s2)); - s21->addTransition(new EventTransition(QEvent::User, s22)); - s22->addTransition(new EventTransition(QEvent::User, s21)); - - machine.start(); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 1); - QVERIFY(machine.configuration().contains(s1)); - QCOMPARE(propertyHolder->property("foo").toInt(), 1); - QCOMPARE(propertyHolder->property("bar").toInt(), 2); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s21)); - QCOMPARE(propertyHolder->property("foo").toInt(), 3); - QCOMPARE(propertyHolder->property("bar").toInt(), 4); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s22)); - QCOMPARE(propertyHolder->property("foo").toInt(), 6); - QCOMPARE(propertyHolder->property("bar").toInt(), 5); - - machine.postEvent(new QEvent(QEvent::User)); - QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().size(), 2); - QVERIFY(machine.configuration().contains(s2)); - QVERIFY(machine.configuration().contains(s21)); - QCOMPARE(propertyHolder->property("foo").toInt(), 3); - QCOMPARE(propertyHolder->property("bar").toInt(), 4); - -} - - -QTEST_MAIN(tst_QStateMachine) -#include "tst_qstatemachine.moc" diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index 4c39373..8e2c243 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -1,7 +1,6 @@ TEMPLATE = subdirs SUBDIRS = containers-associative \ containers-sequential \ - qanimation \ qbytearray \ qpainter \ qtestlib-simple events \ diff --git a/tests/benchmarks/qanimation/dummyanimation.cpp b/tests/benchmarks/qanimation/dummyanimation.cpp deleted file mode 100644 index 6fb1d0a..0000000 --- a/tests/benchmarks/qanimation/dummyanimation.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "dummyanimation.h" -#include "dummyobject.h" - - -DummyAnimation::DummyAnimation(DummyObject *d) : m_dummy(d) -{ -} - -void DummyAnimation::updateCurrentValue(const QVariant &value) -{ - if (state() == Stopped) - return; - if (m_dummy) - m_dummy->setRect(value.toRect()); -} - -void DummyAnimation::updateState(State state) -{ - Q_UNUSED(state); -} diff --git a/tests/benchmarks/qanimation/dummyanimation.h b/tests/benchmarks/qanimation/dummyanimation.h deleted file mode 100644 index fe6592b..0000000 --- a/tests/benchmarks/qanimation/dummyanimation.h +++ /dev/null @@ -1,19 +0,0 @@ -#include - -#ifndef _DUMMYANIMATION_H__ - -class DummyObject; - -class DummyAnimation : public QVariantAnimation -{ -public: - DummyAnimation(DummyObject *d); - - void updateCurrentValue(const QVariant &value); - void updateState(State state); - -private: - DummyObject *m_dummy; -}; - -#endif \ No newline at end of file diff --git a/tests/benchmarks/qanimation/dummyobject.cpp b/tests/benchmarks/qanimation/dummyobject.cpp deleted file mode 100644 index bd76388..0000000 --- a/tests/benchmarks/qanimation/dummyobject.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "dummyobject.h" - -DummyObject::DummyObject() -{ -} - -QRect DummyObject::rect() const -{ - return m_rect; -} - -void DummyObject::setRect(const QRect &r) -{ - m_rect = r; -} - -float DummyObject::opacity() const -{ - return m_opacity; -} - -void DummyObject::setOpacity(float o) -{ - m_opacity = o; -} diff --git a/tests/benchmarks/qanimation/dummyobject.h b/tests/benchmarks/qanimation/dummyobject.h deleted file mode 100644 index c989662..0000000 --- a/tests/benchmarks/qanimation/dummyobject.h +++ /dev/null @@ -1,23 +0,0 @@ -#include - -#ifndef _DUMMYOBJECT_H__ - -class DummyObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(QRect rect READ rect WRITE setRect) - Q_PROPERTY(float opacity READ opacity WRITE setOpacity) -public: - DummyObject(); - QRect rect() const; - void setRect(const QRect &r); - float opacity() const; - void setOpacity(float); - -private: - QRect m_rect; - float m_opacity; -}; - - -#endif \ No newline at end of file diff --git a/tests/benchmarks/qanimation/main.cpp b/tests/benchmarks/qanimation/main.cpp deleted file mode 100644 index 7bb770f..0000000 --- a/tests/benchmarks/qanimation/main.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include - -#include "dummyobject.h" -#include "dummyanimation.h" -#include "rectanimation.h" - -#define ITERATION_COUNT 10e3 - -class tst_qanimation : public QObject -{ - Q_OBJECT -private slots: - void itemPropertyAnimation(); - void itemPropertyAnimation_data() { data();} - void dummyAnimation(); - void dummyAnimation_data() { data();} - void dummyPropertyAnimation(); - void dummyPropertyAnimation_data() { data();} - void rectAnimation(); - void rectAnimation_data() { data();} - - void floatAnimation_data() { data(); } - void floatAnimation(); - -private: - void data(); -}; - - -void tst_qanimation::data() -{ - QTest::addColumn("started"); - QTest::newRow("NotRunning") << false; - QTest::newRow("Running") << true; -} - -void tst_qanimation::itemPropertyAnimation() -{ - QFETCH(bool, started); - QGraphicsWidget item; - - //then the property animation - { - QPropertyAnimation anim(&item, "pos"); - anim.setDuration(ITERATION_COUNT); - anim.setStartValue(QPointF(0,0)); - anim.setEndValue(QPointF(ITERATION_COUNT,ITERATION_COUNT)); - if (started) - anim.start(); - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - anim.setCurrentTime(i); - } - } - } - -} - -void tst_qanimation::dummyAnimation() -{ - QFETCH(bool, started); - DummyObject dummy; - - //first the dummy animation - { - DummyAnimation anim(&dummy); - anim.setDuration(ITERATION_COUNT); - anim.setStartValue(QRect(0, 0, 0, 0)); - anim.setEndValue(QRect(0, 0, ITERATION_COUNT,ITERATION_COUNT)); - if (started) - anim.start(); - QBENCHMARK { - for(int i = 0; i < anim.duration(); ++i) { - anim.setCurrentTime(i); - } - } - } -} - -void tst_qanimation::dummyPropertyAnimation() -{ - QFETCH(bool, started); - DummyObject dummy; - - //then the property animation - { - QPropertyAnimation anim(&dummy, "rect"); - anim.setDuration(ITERATION_COUNT); - anim.setStartValue(QRect(0, 0, 0, 0)); - anim.setEndValue(QRect(0, 0, ITERATION_COUNT,ITERATION_COUNT)); - if (started) - anim.start(); - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - anim.setCurrentTime(i); - } - } - } -} - -void tst_qanimation::rectAnimation() -{ - //this is the simplest animation you can do - QFETCH(bool, started); - DummyObject dummy; - - //then the property animation - { - RectAnimation anim(&dummy); - anim.setDuration(ITERATION_COUNT); - anim.setStartValue(QRect(0, 0, 0, 0)); - anim.setEndValue(QRect(0, 0, ITERATION_COUNT,ITERATION_COUNT)); - if (started) - anim.start(); - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - anim.setCurrentTime(i); - } - } - } -} - -void tst_qanimation::floatAnimation() -{ - //this is the simplest animation you can do - QFETCH(bool, started); - DummyObject dummy; - - //then the property animation - { - QPropertyAnimation anim(&dummy, "opacity"); - anim.setDuration(ITERATION_COUNT); - anim.setStartValue(0.f); - anim.setEndValue(1.f); - if (started) - anim.start(); - QBENCHMARK { - for(int i = 0; i < ITERATION_COUNT; ++i) { - anim.setCurrentTime(i); - } - } - } -} - - - -QTEST_MAIN(tst_qanimation) - -#include "main.moc" diff --git a/tests/benchmarks/qanimation/qanimation.pro b/tests/benchmarks/qanimation/qanimation.pro deleted file mode 100644 index 55cd75e..0000000 --- a/tests/benchmarks/qanimation/qanimation.pro +++ /dev/null @@ -1,18 +0,0 @@ -load(qttest_p4) -TEMPLATE = app -TARGET = tst_qanimation -DEPENDPATH += . -INCLUDEPATH += . - -CONFIG += release -#CONFIG += debug - - -SOURCES += main.cpp \ - dummyobject.cpp \ - dummyanimation.cpp \ - rectanimation.cpp - -HEADERS += dummyobject.h \ - dummyanimation.h \ - rectanimation.h diff --git a/tests/benchmarks/qanimation/rectanimation.cpp b/tests/benchmarks/qanimation/rectanimation.cpp deleted file mode 100644 index d60a943..0000000 --- a/tests/benchmarks/qanimation/rectanimation.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "rectanimation.h" -#include "dummyobject.h" - -static inline int interpolateInteger(int from, int to, qreal progress) -{ - return from + (to - from) * progress; -} - - -RectAnimation::RectAnimation(DummyObject *obj) : m_object(obj), m_dura(250) -{ -} - -void RectAnimation::setEndValue(const QRect &rect) -{ - m_end = rect; -} - -void RectAnimation::setStartValue(const QRect &rect) -{ - m_start = rect; -} - -void RectAnimation::setDuration(int d) -{ - m_dura = d; -} - -int RectAnimation::duration() const -{ - return m_dura; -} - - -void RectAnimation::updateCurrentTime(int msecs) -{ - qreal progress = m_easing.valueForProgress( qreal(msecs) / qreal(m_dura) ); - QRect now; - now.setCoords(interpolateInteger(m_start.left(), m_end.left(), progress), - interpolateInteger(m_start.top(), m_end.top(), progress), - interpolateInteger(m_start.right(), m_end.right(), progress), - interpolateInteger(m_start.bottom(), m_end.bottom(), progress)); - - bool changed = (now != m_current); - if (changed) - m_current = now; - - if (state() == Stopped) - return; - - if (m_object) - m_object->setRect(m_current); -} - -void RectAnimation::updateState(QAbstractAnimation::State state) -{ - Q_UNUSED(state); -} diff --git a/tests/benchmarks/qanimation/rectanimation.h b/tests/benchmarks/qanimation/rectanimation.h deleted file mode 100644 index 99b82b4..0000000 --- a/tests/benchmarks/qanimation/rectanimation.h +++ /dev/null @@ -1,30 +0,0 @@ -#include - -#ifndef _RECTANIMATION_H__ - -class DummyObject; - -//this class is even simpler than the dummy -//and uses no QVariant at all -class RectAnimation : public QAbstractAnimation -{ -public: - RectAnimation(DummyObject *obj); - - void setEndValue(const QRect &rect); - void setStartValue(const QRect &rect); - - void setDuration(int d); - int duration() const; - - virtual void updateCurrentTime(int msecs); - virtual void updateState(QAbstractAnimation::State state); - -private: - DummyObject *m_object; - QEasingCurve m_easing; - QRect m_start, m_end, m_current; - int m_dura; -}; - -#endif diff --git a/tests/benchmarks/qvariant/qvariant.pro b/tests/benchmarks/qvariant/qvariant.pro index 63b5442..68b4a97 100644 --- a/tests/benchmarks/qvariant/qvariant.pro +++ b/tests/benchmarks/qvariant/qvariant.pro @@ -3,6 +3,7 @@ TEMPLATE = app TARGET = tst_qvariant DEPENDPATH += . INCLUDEPATH += . +QT -= gui CONFIG += release #CONFIG += debug diff --git a/tests/benchmarks/qvariant/tst_qvariant.cpp b/tests/benchmarks/qvariant/tst_qvariant.cpp index 0eb1ae2..4a7ad02 100644 --- a/tests/benchmarks/qvariant/tst_qvariant.cpp +++ b/tests/benchmarks/qvariant/tst_qvariant.cpp @@ -38,9 +38,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - #include -#include #include #define ITERATION_COUNT 1e5 @@ -49,73 +47,64 @@ class tst_qvariant : public QObject { Q_OBJECT private slots: - void testBound(); - void doubleVariantCreation(); void floatVariantCreation(); void rectVariantCreation(); void stringVariantCreation(); - void pixmapVariantCreation(); - void doubleVariantSetValue(); void floatVariantSetValue(); void rectVariantSetValue(); void stringVariantSetValue(); - void doubleVariantAssignment(); void floatVariantAssignment(); void rectVariantAssignment(); void stringVariantAssignment(); }; -void tst_qvariant::testBound() + +void tst_qvariant::doubleVariantCreation() { - qreal d = qreal(.5); + double d = 0; QBENCHMARK { for(int i = 0; i < ITERATION_COUNT; ++i) { - d = qBound(0, d, 1); + QVariant v(d); } } } -template -static void variantCreation(T val) +void tst_qvariant::floatVariantCreation() { + float f = 0; QBENCHMARK { for(int i = 0; i < ITERATION_COUNT; ++i) { - QVariant v(val); + QVariant v(f); } } } -void tst_qvariant::doubleVariantCreation() -{ - variantCreation(0.0); -} - -void tst_qvariant::floatVariantCreation() -{ - variantCreation(0.0f); -} - void tst_qvariant::rectVariantCreation() { - variantCreation(QRect(1, 2, 3, 4)); + QRect r(1,2,3,4); + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + QVariant v(r); + } + } } void tst_qvariant::stringVariantCreation() { - variantCreation(QString()); -} - -void tst_qvariant::pixmapVariantCreation() -{ - variantCreation(QPixmap()); + QString s; + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + QVariant v(s); + } + } } -template -static void variantSetValue(T d) +void tst_qvariant::doubleVariantSetValue() { + double d = 0; QVariant v; QBENCHMARK { for(int i = 0; i < ITERATION_COUNT; ++i) { @@ -124,55 +113,81 @@ static void variantSetValue(T d) } } -void tst_qvariant::doubleVariantSetValue() -{ - variantSetValue(0.0); -} - void tst_qvariant::floatVariantSetValue() { - variantSetValue(0.0f); + float f = 0; + QVariant v; + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + qVariantSetValue(v, f); + } + } } void tst_qvariant::rectVariantSetValue() { - variantSetValue(QRect()); + QRect r; + QVariant v; + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + qVariantSetValue(v, r); + } + } } void tst_qvariant::stringVariantSetValue() { - variantSetValue(QString()); -} - -template -static void variantAssignment(T d) -{ + QString s; QVariant v; QBENCHMARK { for(int i = 0; i < ITERATION_COUNT; ++i) { - v = d; + qVariantSetValue(v, s); } } } void tst_qvariant::doubleVariantAssignment() { - variantAssignment(0.0); + double d = 0; + QVariant v; + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + v = d; + } + } } void tst_qvariant::floatVariantAssignment() { - variantAssignment(0.0f); + float f = 0; + QVariant v; + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + v = f; + } + } } void tst_qvariant::rectVariantAssignment() { - variantAssignment(QRect()); + QRect r; + QVariant v; + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + v = r; + } + } } void tst_qvariant::stringVariantAssignment() { - variantAssignment(QString()); + QString s; + QVariant v; + QBENCHMARK { + for(int i = 0; i < ITERATION_COUNT; ++i) { + v = s; + } + } } QTEST_MAIN(tst_qvariant) -- cgit v0.12 From a97862318a6b3f72a05a3e66ebcf5f0e455bb42a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 11 Apr 2008 13:12:02 +0200 Subject: Don't use memcmp it's terribly slow. Added qMemEquals method that returns true if the two memory regions contain the same content. Reviewed-By: Thiago Macieira --- src/corelib/tools/qstring.cpp | 152 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 6 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index c3649e3..81b55b7 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -195,6 +195,142 @@ static int ucstrnicmp(const ushort *a, const ushort *b, int l) return ucstricmp(a, a + l, b, b + l); } +#if 0 +static bool qMemEquals(const quint8 *a, const quint8 *b, int bytes) +{ + if (a == b) + return true; + + // check alignement + qptrdiff align = ((quintptr)a - (quintptr)b); +// if (sizeof(void *) == 8 && !(align & 7)) { +// } else + if (!(align & 3)) { + quintptr pa = (quintptr)a; + if (pa & 3) { + if (pa & 1) { + if (*a != *b) + return false; + ++a; + ++b; + --bytes; + } + if (pa & 2) { + if (*reinterpret_cast(a) != *reinterpret_cast(b)) + return false; + a += 2; + b += 2; + bytes -= 2; + } + } + int tail = (bytes & 3); + const quint32 *sa = reinterpret_cast(a); + const quint32 *sb = reinterpret_cast(b); + const quint32 *e = sa + (bytes >> 2); + while (sa < e) { + if (*sa != *sb) + return false; + ++sa; + ++sb; + } + a = reinterpret_cast(sa); + b = reinterpret_cast(sb); + if (tail) { + if (tail & 2) { + if (*reinterpret_cast(a) != *reinterpret_cast(b)) + return false; + sa += 2; + sb += 2; + } + if (tail & 1) { + if (*a != *b) + return false; + } + } + } else if (!(align & 1)) { + quintptr pa = (quintptr)a; + if (pa & 1) { + if (*a != *b) + return false; + ++a; + ++b; + --bytes; + } + bool tail = (bytes & 1); + const quint16 *sa = reinterpret_cast(a); + const quint16 *sb = reinterpret_cast(b); + const quint16 *e = sa + (bytes >> 1); + while (sa < e) { + if (*sa != *sb) + return false; + ++sa; + ++sb; + } + a = reinterpret_cast(sa); + b = reinterpret_cast(sb); + if (tail) { + if (*a != *b) + return false; + } + } else { + const quint8 *e = a + bytes; + while (a < e) { + if (*a != *b) + return false; + ++a; + ++b; + } + } + return true; +} +#endif + +static bool qMemEquals(const quint16 *a, const quint16 *b, int length) +{ + if (a == b) + return true; + + // check alignement + qptrdiff align = ((quintptr)a - (quintptr)b); + Q_ASSERT(!(align & 1)); +// if (sizeof(void *) == 8 && !(align & 7)) { +// } else + if (!(align & 3)) { + quintptr pa = (quintptr)a; + if (pa & 2) { + if (*a != *b) + return false; + ++a; + ++b; + --length; + } + int tail = (length & 1); + const quint32 *sa = reinterpret_cast(a); + const quint32 *sb = reinterpret_cast(b); + const quint32 *e = sa + (length >> 1); + while (sa < e) { + if (*sa != *sb) + return false; + ++sa; + ++sb; + } + a = reinterpret_cast(sa); + b = reinterpret_cast(sb); + if (tail) { + if (*a != *b) + return false; + } + } else if (!(align & 1)) { + const quint16 *e = a + length; + while (a < e) { + if (*a != *b) + return false; + ++a; + ++b; + } + } + return true; +} /*! \internal @@ -1908,8 +2044,10 @@ QString &QString::replace(QChar c, const QLatin1String &after, Qt::CaseSensitivi */ bool QString::operator==(const QString &other) const { - return (size() == other.size()) && - (memcmp((char*)unicode(),(char*)other.unicode(), size()*sizeof(QChar))==0); + if (d->size != other.d->size) + return false; + + return qMemEquals(d->data, other.d->data, d->size); } /*! @@ -3136,7 +3274,7 @@ bool QString::startsWith(const QString& s, Qt::CaseSensitivity cs) const if (s.d->size > d->size) return false; if (cs == Qt::CaseSensitive) { - return memcmp((char*)d->data, (char*)s.d->data, s.d->size*sizeof(QChar)) == 0; + return qMemEquals(d->data, s.d->data, s.d->size); } else { uint last = 0; uint olast = 0; @@ -3207,7 +3345,7 @@ bool QString::endsWith(const QString& s, Qt::CaseSensitivity cs) const if (pos < 0) return false; if (cs == Qt::CaseSensitive) { - return memcmp((char*)&d->data[pos], (char*)s.d->data, s.d->size*sizeof(QChar)) == 0; + return qMemEquals(d->data + pos, s.d->data, s.d->size); } else { uint last = 0; uint olast = 0; @@ -7692,7 +7830,8 @@ QString QStringRef::toString() const { */ bool operator==(const QStringRef &s1,const QStringRef &s2) { return (s1.size() == s2.size() && - (memcmp((char*)s1.unicode(), (char*)s2.unicode(), s1.size()*sizeof(QChar))==0)); } + qMemEquals((const ushort *)s1.unicode(), (const ushort *)s2.unicode(), s1.size())); +} /*! \relates QStringRef @@ -7701,7 +7840,8 @@ bool operator==(const QStringRef &s1,const QStringRef &s2) */ bool operator==(const QString &s1,const QStringRef &s2) { return (s1.size() == s2.size() && - (memcmp((char*)s1.unicode(), (char*)s2.unicode(), s1.size()*sizeof(QChar))==0)); } + qMemEquals((const ushort *)s1.unicode(), (const ushort *)s2.unicode(), s1.size())); +} /*! \relates QStringRef -- cgit v0.12 From 7c848d093e2ce12528d8af435a6e10bc0e28f1e3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 18 May 2009 23:24:03 +0200 Subject: Add a benchmark for QString::operator== Reviewed-By: Bradley T. Hughes --- tests/benchmarks/qstring/main.cpp | 104 +++++++++++++++++++++++++++++++++++ tests/benchmarks/qstring/qstring.pro | 4 ++ 2 files changed, 108 insertions(+) create mode 100644 tests/benchmarks/qstring/main.cpp create mode 100644 tests/benchmarks/qstring/qstring.pro diff --git a/tests/benchmarks/qstring/main.cpp b/tests/benchmarks/qstring/main.cpp new file mode 100644 index 0000000..c7962bd --- /dev/null +++ b/tests/benchmarks/qstring/main.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include + +class tst_QString: public QObject +{ + Q_OBJECT +private slots: + void equals() const; + void equals_data() const; +}; + +void tst_QString::equals() const +{ + QFETCH(QString, a); + QFETCH(QString, b); + + QBENCHMARK { + a == b; + } +} + +void tst_QString::equals_data() const +{ + static const struct { + ushort data[80]; + int dummy; // just to ensure 4-byte alignment + } data = { + { + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, // 16 + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, // 32 + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, // 48 + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, // 64 + 64, 64, 64, 64, 64, 64, 64, 64, + 96, 96, 96, 96, 96, 96, 96, 96 // 80 + }, 0 + }; + const QChar *ptr = reinterpret_cast(data.data); + + QTest::addColumn("a"); + QTest::addColumn("b"); + QString base = QString::fromRawData(ptr, 64); + + QTest::newRow("different-length") << base << QString::fromRawData(ptr, 4); + QTest::newRow("same-string") << base << base; + QTest::newRow("same-data") << base << QString::fromRawData(ptr, 64); + + // don't use length > 64, since that crosses a cache line + QTest::newRow("aligned-odd") + << QString::fromRawData(ptr, 63) << QString::fromRawData(ptr + 2, 63); + QTest::newRow("aligned-even") + << QString::fromRawData(ptr, 64) << QString::fromRawData(ptr + 2, 64); + QTest::newRow("unaligned-even") + << QString::fromRawData(ptr, 63) << QString::fromRawData(ptr + 1, 63); + QTest::newRow("unaligned-odd") + << QString::fromRawData(ptr, 64) << QString::fromRawData(ptr + 1, 64); +} + +QTEST_MAIN(tst_QString) + +#include "main.moc" diff --git a/tests/benchmarks/qstring/qstring.pro b/tests/benchmarks/qstring/qstring.pro new file mode 100644 index 0000000..74423e7 --- /dev/null +++ b/tests/benchmarks/qstring/qstring.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +TARGET = tst_qstring +QT -= gui +SOURCES += main.cpp -- cgit v0.12 From 2387c77787ec279981d58c46cfb5bde3e1530790 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 18 May 2009 23:24:26 +0200 Subject: Optimise QString comparison based on the results from the benchmark Reviewed-By: Bradley T. Hughes --- src/corelib/tools/qstring.cpp | 163 ++++++++++-------------------------------- 1 file changed, 38 insertions(+), 125 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 81b55b7..456fdfd 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -195,139 +195,52 @@ static int ucstrnicmp(const ushort *a, const ushort *b, int l) return ucstricmp(a, a + l, b, b + l); } -#if 0 -static bool qMemEquals(const quint8 *a, const quint8 *b, int bytes) +static bool qMemEquals(const quint16 *a, const quint16 *b, int length) { + // Benchmarking indicates that doing memcmp is much slower than + // executing the comparison ourselves. + // To make it even faster, we do a 32-bit comparison, comparing + // twice the amount of data as a normal word-by-word comparison. + // + // Benchmarking results on a 2.33 GHz Core2 Duo, with a 64-QChar + // block of data, with 4194304 iterations (per iteration): + // operation usec cpu ticks + // memcmp 330 710 + // 16-bit 135 285-290 + // 32-bit aligned 69.7 135-145 + // + // Testing also indicates that unaligned 32-bit loads are as + // performant as 32-bit aligned. if (a == b) return true; - // check alignement - qptrdiff align = ((quintptr)a - (quintptr)b); -// if (sizeof(void *) == 8 && !(align & 7)) { -// } else - if (!(align & 3)) { - quintptr pa = (quintptr)a; - if (pa & 3) { - if (pa & 1) { - if (*a != *b) - return false; - ++a; - ++b; - --bytes; - } - if (pa & 2) { - if (*reinterpret_cast(a) != *reinterpret_cast(b)) - return false; - a += 2; - b += 2; - bytes -= 2; - } - } - int tail = (bytes & 3); - const quint32 *sa = reinterpret_cast(a); - const quint32 *sb = reinterpret_cast(b); - const quint32 *e = sa + (bytes >> 2); - while (sa < e) { - if (*sa != *sb) - return false; - ++sa; - ++sb; - } - a = reinterpret_cast(sa); - b = reinterpret_cast(sb); - if (tail) { - if (tail & 2) { - if (*reinterpret_cast(a) != *reinterpret_cast(b)) - return false; - sa += 2; - sb += 2; - } - if (tail & 1) { - if (*a != *b) - return false; - } - } - } else if (!(align & 1)) { - quintptr pa = (quintptr)a; - if (pa & 1) { - if (*a != *b) - return false; - ++a; - ++b; - --bytes; - } - bool tail = (bytes & 1); - const quint16 *sa = reinterpret_cast(a); - const quint16 *sb = reinterpret_cast(b); - const quint16 *e = sa + (bytes >> 1); - while (sa < e) { - if (*sa != *sb) - return false; - ++sa; - ++sb; - } - a = reinterpret_cast(sa); - b = reinterpret_cast(sb); - if (tail) { - if (*a != *b) - return false; - } - } else { - const quint8 *e = a + bytes; - while (a < e) { - if (*a != *b) + register union { + const quint16 *w; + const quint32 *d; + quintptr value; + } sa, sb; + sa.w = a; + sb.w = b; + + // check alignment + bool unaligned = (sa.value | sb.value) & 2; +#if defined(__i386__) || defined(__x86_64__) || defined(_M_X64_) + unaligned = false; +#endif + if (!unaligned) { + // both addresses are 4-bytes aligned (or this is an x86) + // do a fast 32-bit comparison + for (register int halfLength = length / 2; halfLength; --halfLength, ++sa.d, ++sb.d) { + if (*sa.d != *sb.d) return false; - ++a; - ++b; } + return length & 1 ? (*sa.w == *sb.w) : true; } - return true; -} -#endif -static bool qMemEquals(const quint16 *a, const quint16 *b, int length) -{ - if (a == b) - return true; - - // check alignement - qptrdiff align = ((quintptr)a - (quintptr)b); - Q_ASSERT(!(align & 1)); -// if (sizeof(void *) == 8 && !(align & 7)) { -// } else - if (!(align & 3)) { - quintptr pa = (quintptr)a; - if (pa & 2) { - if (*a != *b) - return false; - ++a; - ++b; - --length; - } - int tail = (length & 1); - const quint32 *sa = reinterpret_cast(a); - const quint32 *sb = reinterpret_cast(b); - const quint32 *e = sa + (length >> 1); - while (sa < e) { - if (*sa != *sb) - return false; - ++sa; - ++sb; - } - a = reinterpret_cast(sa); - b = reinterpret_cast(sb); - if (tail) { - if (*a != *b) - return false; - } - } else if (!(align & 1)) { - const quint16 *e = a + length; - while (a < e) { - if (*a != *b) - return false; - ++a; - ++b; - } + // one or both of the addresses isn't 2-byte aligned + for ( ; length; --length, ++sa.w, ++sb.w) { + if (*sa.w != *sb.w) + return false; } return true; } -- cgit v0.12 From 1ff30b2b88af31cf18d2a1e6961c3ed7bd9b0240 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 19 May 2009 14:38:49 +0200 Subject: Reintroduce the unaligned-unaligned 32-bit code that I had removed out of ignorance. If both pointers are out of 4-byte alignment, doing the first load will align them so we can do 32-bit comparisons. Lars's code had this before, but I misunderstood it and removed, thinking it was doing misaligned accesses. I experimented with moving the tail comparison above the 32-bit comparison to save a register, but it made things worse. Reviewed-By: Bradley T. Hughes --- src/corelib/tools/qstring.cpp | 45 +++++++++++++++++++++++++-------------- tests/benchmarks/qstring/main.cpp | 41 +++++++++++++++++++++++++---------- 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 456fdfd..29509c5 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -206,12 +206,12 @@ static bool qMemEquals(const quint16 *a, const quint16 *b, int length) // block of data, with 4194304 iterations (per iteration): // operation usec cpu ticks // memcmp 330 710 - // 16-bit 135 285-290 - // 32-bit aligned 69.7 135-145 + // 16-bit 79 167-171 + // 32-bit aligned 49 105-109 // // Testing also indicates that unaligned 32-bit loads are as // performant as 32-bit aligned. - if (a == b) + if (a == b || !length) return true; register union { @@ -223,24 +223,37 @@ static bool qMemEquals(const quint16 *a, const quint16 *b, int length) sb.w = b; // check alignment - bool unaligned = (sa.value | sb.value) & 2; -#if defined(__i386__) || defined(__x86_64__) || defined(_M_X64_) - unaligned = false; -#endif - if (!unaligned) { - // both addresses are 4-bytes aligned (or this is an x86) + if ((sa.value & 2) == (sb.value & 2)) { + // both addresses have the same alignment + if (sa.value & 2) { + // both addresses are not aligned to 4-bytes boundaries + // compare the first character + if (*sa.w != *sb.w) + return false; + --length; + ++sa.w; + ++sb.w; + + // now both addresses are 4-bytes aligned + } + + // both addresses are 4-bytes aligned // do a fast 32-bit comparison - for (register int halfLength = length / 2; halfLength; --halfLength, ++sa.d, ++sb.d) { + register const quint32 *e = sa.d + (length >> 1); + for ( ; sa.d != e; ++sa.d, ++sb.d) { if (*sa.d != *sb.d) return false; } - return length & 1 ? (*sa.w == *sb.w) : true; - } - // one or both of the addresses isn't 2-byte aligned - for ( ; length; --length, ++sa.w, ++sb.w) { - if (*sa.w != *sb.w) - return false; + // do we have a tail? + return (length & 1) ? *sa.w == *sb.w : true; + } else { + // one of the addresses isn't 4-byte aligned but the other is + register const quint16 *e = sa.w + length; + for ( ; sa.w != e; ++sa.w, ++sb.w) { + if (*sa.w != *sb.w) + return false; + } } return true; } diff --git a/tests/benchmarks/qstring/main.cpp b/tests/benchmarks/qstring/main.cpp index c7962bd..cbbf0a1 100644 --- a/tests/benchmarks/qstring/main.cpp +++ b/tests/benchmarks/qstring/main.cpp @@ -74,8 +74,8 @@ void tst_QString::equals_data() const 64, 64, 64, 64, 64, 64, 64, 64, // 48 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 64 - 64, 64, 64, 64, 64, 64, 64, 64, - 96, 96, 96, 96, 96, 96, 96, 96 // 80 + 64, 64, 64, 64, 96, 96, 96, 96, + 64, 64, 96, 96, 96, 96, 96, 96 // 80 }, 0 }; const QChar *ptr = reinterpret_cast(data.data); @@ -88,15 +88,34 @@ void tst_QString::equals_data() const QTest::newRow("same-string") << base << base; QTest::newRow("same-data") << base << QString::fromRawData(ptr, 64); - // don't use length > 64, since that crosses a cache line - QTest::newRow("aligned-odd") - << QString::fromRawData(ptr, 63) << QString::fromRawData(ptr + 2, 63); - QTest::newRow("aligned-even") - << QString::fromRawData(ptr, 64) << QString::fromRawData(ptr + 2, 64); - QTest::newRow("unaligned-even") - << QString::fromRawData(ptr, 63) << QString::fromRawData(ptr + 1, 63); - QTest::newRow("unaligned-odd") - << QString::fromRawData(ptr, 64) << QString::fromRawData(ptr + 1, 64); + // try to avoid crossing a cache line (that is, at ptr[64]) + QTest::newRow("aligned-aligned-4n") + << QString::fromRawData(ptr, 60) << QString::fromRawData(ptr + 2, 60); + QTest::newRow("aligned-unaligned-4n") + << QString::fromRawData(ptr, 60) << QString::fromRawData(ptr + 1, 60); + QTest::newRow("unaligned-unaligned-4n") + << QString::fromRawData(ptr + 1, 60) << QString::fromRawData(ptr + 3, 60); + + QTest::newRow("aligned-aligned-4n+1") + << QString::fromRawData(ptr, 61) << QString::fromRawData(ptr + 2, 61); + QTest::newRow("aligned-unaligned-4n+1") + << QString::fromRawData(ptr, 61) << QString::fromRawData(ptr + 1, 61); + QTest::newRow("unaligned-unaligned-4n+1") + << QString::fromRawData(ptr + 1, 61) << QString::fromRawData(ptr + 3, 61); + + QTest::newRow("aligned-aligned-4n-1") + << QString::fromRawData(ptr, 59) << QString::fromRawData(ptr + 2, 59); + QTest::newRow("aligned-unaligned-4n-1") + << QString::fromRawData(ptr, 59) << QString::fromRawData(ptr + 1, 59); + QTest::newRow("unaligned-unaligned-4n-1") + << QString::fromRawData(ptr + 1, 59) << QString::fromRawData(ptr + 3, 59); + + QTest::newRow("aligned-aligned-2n") + << QString::fromRawData(ptr, 58) << QString::fromRawData(ptr + 2, 58); + QTest::newRow("aligned-unaligned-2n") + << QString::fromRawData(ptr, 58) << QString::fromRawData(ptr + 1, 58); + QTest::newRow("unaligned-unaligned-2n") + << QString::fromRawData(ptr + 1, 58) << QString::fromRawData(ptr + 3, 58); } QTEST_MAIN(tst_QString) -- cgit v0.12 From 759b7ee720fa365f93fe02ecb5b842adce81d02d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 22 May 2009 14:14:31 +0200 Subject: Fixed potential bug caused by change b89efc8e7f32. If ensureSpace causes the layoutData to reallocate then the initialGlyphs pointers will no longer be valid. Reviewed-by: Simon Hausmann --- src/gui/text/qtextengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index da1ab25..d41d414 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1219,7 +1219,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const QFontEngine *actualFontEngine = font; uint engineIdx = 0; if (font->type() == QFontEngine::Multi) { - engineIdx = uint(initialGlyphs.glyphs[glyph_pos] >> 24); + engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24); actualFontEngine = static_cast(font)->engine(engineIdx); } -- cgit v0.12 From 1cfb5bcaa2cab142479ee975e25d9f605f852dad Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 22 May 2009 14:30:01 +0200 Subject: Don't loop around sigaction because it can't return EINTR. Asked by Oswald. Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess_unix.cpp | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 33d4a47..1fedd55 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -140,15 +140,6 @@ static void qt_native_close(int fd) } while (ret == -1 && errno == EINTR); } -static void qt_native_sigaction(int signum, const struct sigaction *act, - struct sigaction *oldact) -{ - int ret; - do { - ret = ::sigaction(signum, act, oldact); - } while (ret == -1 && errno == EINTR); -} - static void qt_native_dup2(int oldfd, int newfd) { int ret; @@ -255,7 +246,7 @@ QProcessManager::QProcessManager() memset(&action, 0, sizeof(action)); action.sa_handler = qt_sa_sigchld_handler; action.sa_flags = SA_NOCLDSTOP; - qt_native_sigaction(SIGCHLD, &action, &oldAction); + ::sigaction(SIGCHLD, &action, &oldAction); if (oldAction.sa_handler != qt_sa_sigchld_handler) qt_sa_old_sigchld_handler = oldAction.sa_handler; } @@ -282,9 +273,9 @@ QProcessManager::~QProcessManager() memset(&action, 0, sizeof(action)); action.sa_handler = qt_sa_old_sigchld_handler; action.sa_flags = SA_NOCLDSTOP; - qt_native_sigaction(SIGCHLD, &action, &oldAction); + ::sigaction(SIGCHLD, &action, &oldAction); if (oldAction.sa_handler != qt_sa_sigchld_handler) { - qt_native_sigaction(SIGCHLD, &oldAction, 0); + ::sigaction(SIGCHLD, &oldAction, 0); } } @@ -900,7 +891,7 @@ static void qt_ignore_sigpipe() struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; - qt_native_sigaction(SIGPIPE, &noaction, 0); + ::sigaction(SIGPIPE, &noaction, 0); } } @@ -1270,7 +1261,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; - qt_native_sigaction(SIGPIPE, &noaction, 0); + ::sigaction(SIGPIPE, &noaction, 0); ::setsid(); @@ -1316,7 +1307,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; - qt_native_sigaction(SIGPIPE, &noaction, 0); + ::sigaction(SIGPIPE, &noaction, 0); // '\1' means execv failed char c = '\1'; @@ -1327,7 +1318,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; - qt_native_sigaction(SIGPIPE, &noaction, 0); + ::sigaction(SIGPIPE, &noaction, 0); // '\2' means internal error char c = '\2'; -- cgit v0.12 From 562adecf4f938f593674f03b425a79b89e238518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Apr 2009 14:17:20 +0200 Subject: Don't block copy sequential files in QFile::rename Block copying a sequential file is potentially a destructive operation, because there is no guarantee copy+remove will succeed. In these cases the fallback should not be tried. The user is better equipped to decide how to handle such failures and to ensure no data losses occur, e.g., copy without removing the original file. Reviewed-by: MariusSO Reviewed-by: Peter Hartmann Reviewed-by: Thiago --- src/corelib/io/qfile.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index d7da800..4110494 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -718,6 +718,11 @@ QFile::rename(const QString &newName) return true; } + if (isSequential()) { + d->setError(QFile::RenameError, tr("Will not rename sequential file using block copy")); + return false; + } + QFile in(fileName()); QFile out(newName); if (in.open(QIODevice::ReadOnly)) { -- cgit v0.12 From f1e9c0f3d22d611bfaa14c30a34e6042500a0cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Apr 2009 14:24:43 +0200 Subject: Allow renaming QTemporaryFiles on windows Changed the fallback implementation to use 'this' instead of a new QFile. This allows a QTemporaryFile to be block-copied to the destination and the source to be removed (QTemporaryFile is special because it isn't really closed). Reviewed-by: Peter Hartmann Reviewed-by: Thiago --- src/corelib/io/qfile.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 4110494..d3cee9a 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -723,26 +723,25 @@ QFile::rename(const QString &newName) return false; } - QFile in(fileName()); QFile out(newName); - if (in.open(QIODevice::ReadOnly)) { + if (open(QIODevice::ReadOnly)) { if (out.open(QIODevice::WriteOnly | QIODevice::Truncate)) { bool error = false; char block[4096]; - qint64 read; - while ((read = in.read(block, sizeof(block))) > 0) { - if (read != out.write(block, read)) { + qint64 bytes; + while ((bytes = read(block, sizeof(block))) > 0) { + if (bytes != out.write(block, bytes)) { d->setError(QFile::RenameError, out.errorString()); error = true; break; } } - if (read == -1) { - d->setError(QFile::RenameError, in.errorString()); + if (bytes == -1) { + d->setError(QFile::RenameError, errorString()); error = true; } if(!error) { - if (!in.remove()) { + if (!remove()) { d->setError(QFile::RenameError, tr("Cannot remove source file")); error = true; } @@ -751,10 +750,12 @@ QFile::rename(const QString &newName) out.remove(); else setFileName(newName); + close(); return !error; } + close(); } - d->setError(QFile::RenameError, out.isOpen() ? in.errorString() : out.errorString()); + d->setError(QFile::RenameError, out.isOpen() ? errorString() : out.errorString()); } return false; } -- cgit v0.12 From fd7cb7faa765835de6e7beb24f018c417d9ad7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 13 May 2009 17:13:48 +0200 Subject: QFile::copy: close source file when using fallback mechanism Also added check in test case for rename fallback. Task-number: 165920 Reviewed-by: Thiago --- src/corelib/io/qfile.cpp | 1 + tests/auto/qfile/copy-fallback.qrc | 5 +++++ tests/auto/qfile/test/test.pro | 2 +- tests/auto/qfile/tst_qfile.cpp | 30 ++++++++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/auto/qfile/copy-fallback.qrc diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index d3cee9a..a0bd8b4 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -914,6 +914,7 @@ QFile::copy(const QString &newName) out.setAutoRemove(false); #endif } + close(); } if(!error) { QFile::setPermissions(newName, permissions()); diff --git a/tests/auto/qfile/copy-fallback.qrc b/tests/auto/qfile/copy-fallback.qrc new file mode 100644 index 0000000..864491f --- /dev/null +++ b/tests/auto/qfile/copy-fallback.qrc @@ -0,0 +1,5 @@ + + + copy-fallback.qrc + + diff --git a/tests/auto/qfile/test/test.pro b/tests/auto/qfile/test/test.pro index 68f4c05..8d26f5e 100644 --- a/tests/auto/qfile/test/test.pro +++ b/tests/auto/qfile/test/test.pro @@ -17,7 +17,7 @@ QT = core network DEFINES += SRCDIR=\\\"$$PWD/../\\\" } -RESOURCES += ../qfile.qrc ../rename-fallback.qrc +RESOURCES += ../qfile.qrc ../rename-fallback.qrc ../copy-fallback.qrc TARGET = ../tst_qfile diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 98e1859..7e28d12 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -125,6 +125,7 @@ private slots: void copy(); void copyRemovesTemporaryFile() const; void copyShouldntOverwrite(); + void copyFallback(); void link(); void linkToDir(); void absolutePathLinkToRelativePath(); @@ -213,6 +214,9 @@ void tst_QFile::cleanup() // TODO: Add cleanup code here. // This will be executed immediately after each test is run. + // for copyFallback() + QFile::remove("file-copy-destination.txt"); + // for renameFallback() QFile::remove("file-rename-destination.txt"); @@ -907,6 +911,31 @@ void tst_QFile::copyShouldntOverwrite() QFile::remove("tst_qfile.cpy"); } +void tst_QFile::copyFallback() +{ + // Using a resource file to trigger QFile::copy's fallback handling + QFile file(":/copy-fallback.qrc"); + QFile::remove("file-copy-destination.txt"); + + QVERIFY2(file.exists(), "test precondition"); + QVERIFY2(!QFile::exists("file-copy-destination.txt"), "test precondition"); + + // Fallback copy of closed file. + QVERIFY(file.copy("file-copy-destination.txt")); + QVERIFY(QFile::exists("file-copy-destination.txt")); + QVERIFY(!file.isOpen()); + + QVERIFY(QFile::remove("file-copy-destination.txt")); + + // Fallback copy of open file. + QVERIFY(file.open(QIODevice::ReadOnly)); + QVERIFY(file.copy("file-copy-destination.txt")); + QVERIFY(QFile::exists("file-copy-destination.txt")); + QVERIFY(!file.isOpen()); + + QFile::remove("file-copy-destination.txt"); +} + #ifdef Q_OS_WIN #include #include @@ -2081,6 +2110,7 @@ void tst_QFile::renameFallback() QVERIFY(!file.rename("file-rename-destination.txt")); QVERIFY(!QFile::exists("file-rename-destination.txt")); + QVERIFY(!file.isOpen()); } void tst_QFile::renameMultiple() -- cgit v0.12 From 3580f5b4d002cca714d443054f8cdd6aefca3287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Apr 2009 14:30:47 +0200 Subject: QFile::rename fallback: reset permissions and error state on success Fallback implementation for rename operation should try to copy permissions from the original file to the destination file. Note that failures at this point are not treated as errors. Errors previously set by the native fileEngine are also reset before returning. Reviewed-by: Peter Hartmann Reviewed-by: Thiago --- src/corelib/io/qfile.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index a0bd8b4..10b812b 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -748,8 +748,11 @@ QFile::rename(const QString &newName) } if (error) out.remove(); - else + else { + setPermissions(permissions()); + unsetError(); setFileName(newName); + } close(); return !error; } -- cgit v0.12 From 3672deb3b35fc0660c58a8ecc741b989dd0bfc8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 19 May 2009 14:02:12 +0200 Subject: Fix auto test When copying a resource file to the native file system the (read-only) permissions also get copied. On Windows platforms, this was preventing a test file from being deleted. Reviewed-by: Peter Hartmann Reviewed-by: Thiago --- tests/auto/qfile/tst_qfile.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 7e28d12..9ee4d7c 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -215,7 +215,11 @@ void tst_QFile::cleanup() // This will be executed immediately after each test is run. // for copyFallback() - QFile::remove("file-copy-destination.txt"); + if (QFile::exists("file-copy-destination.txt")) { + QFile::setPermissions("file-copy-destination.txt", + QFile::ReadOwner | QFile::WriteOwner); + QFile::remove("file-copy-destination.txt"); + } // for renameFallback() QFile::remove("file-rename-destination.txt"); @@ -925,6 +929,9 @@ void tst_QFile::copyFallback() QVERIFY(QFile::exists("file-copy-destination.txt")); QVERIFY(!file.isOpen()); + // Need to reset permissions on Windows to be able to delete + QVERIFY(QFile::setPermissions("file-copy-destination.txt", + QFile::ReadOwner | QFile::WriteOwner)); QVERIFY(QFile::remove("file-copy-destination.txt")); // Fallback copy of open file. -- cgit v0.12 From 662e8997e9777c6661dde2134e43e35963a12cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Apr 2009 14:34:57 +0200 Subject: QTemporaryFile: don't clear filePath if remove fails Reviewed-by: MariusSO Reviewed-by: Peter Hartmann Reviewed-by: Thiago --- src/corelib/io/qtemporaryfile.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 6a9125c..b0809c6 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -364,9 +364,11 @@ bool QTemporaryFileEngine::remove() // Since the QTemporaryFileEngine::close() does not really close the file, // we must explicitly call QFSFileEngine::close() before we remove it. QFSFileEngine::close(); - bool removed = QFSFileEngine::remove(); - d->filePath.clear(); - return removed; + if (QFSFileEngine::remove()) { + d->filePath.clear(); + return true; + } + return false; } bool QTemporaryFileEngine::close() -- cgit v0.12 From cfa01206e38d120c0ddb17aec7358aadff30b6f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 18 May 2009 12:40:01 +0200 Subject: QTemporaryFile would forget fileName while file was "closed" Note: this showed even if the file descriptor was kept open. Reviewed-by: Peter Hartmann Reviewed-by: Thiago --- src/corelib/io/qtemporaryfile.cpp | 3 ++- tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index b0809c6..11e88e2 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -603,7 +603,8 @@ void QTemporaryFile::setAutoRemove(bool b) QString QTemporaryFile::fileName() const { - if(!isOpen()) + Q_D(const QTemporaryFile); + if(d->fileName.isEmpty()) return QString(); return fileEngine()->fileName(QAbstractFileEngine::DefaultName); } diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp index 2daa0f6..c6a43ff 100644 --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp @@ -77,6 +77,7 @@ private slots: void fileTemplate_data(); void getSetCheck(); void fileName(); + void fileNameIsEmpty(); void autoRemove(); void write(); void openCloseOpenClose(); @@ -189,6 +190,27 @@ void tst_QTemporaryFile::fileName() QCOMPARE(absoluteFilePath, absoluteTempPath); } +void tst_QTemporaryFile::fileNameIsEmpty() +{ + QString filename; + { + QTemporaryFile file; + QVERIFY(file.fileName().isEmpty()); + + QVERIFY(file.open()); + QVERIFY(!file.fileName().isEmpty()); + + filename = file.fileName(); + QVERIFY(QFile::exists(filename)); + + file.close(); + QVERIFY(!file.isOpen()); + QVERIFY(QFile::exists(filename)); + QVERIFY(!file.fileName().isEmpty()); + } + QVERIFY(!QFile::exists(filename)); +} + void tst_QTemporaryFile::autoRemove() { // Test auto remove @@ -358,6 +380,7 @@ void tst_QTemporaryFile::rename() QVERIFY(file.rename("temporary-file.txt")); QVERIFY(!dir.exists(tempname)); QVERIFY(dir.exists("temporary-file.txt")); + QCOMPARE(file.fileName(), QString("temporary-file.txt")); } QVERIFY(!dir.exists(tempname)); -- cgit v0.12 From 70f616238e77d866420f2c6e12afe04b529fe808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 20 May 2009 20:13:51 +0200 Subject: Documentation fix We souldn't be returning an empty string for the fileName, just because the file is closed. E.g., after a rename, the file will be closed, but should still have a name. Reviewed-by: Thiago --- src/corelib/io/qtemporaryfile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 11e88e2..e83d7e9 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -432,8 +432,8 @@ QTemporaryFilePrivate::~QTemporaryFilePrivate() file will exist and be kept open internally by QTemporaryFile. The file name of the temporary file can be found by calling fileName(). - Note that this is only defined while the file is open; the function returns - an empty string before the file is opened and after it is closed. + Note that this is only defined after the file is first opened; the function + returns an empty string before this. A temporary file will have some static part of the name and some part that is calculated to be unique. The default filename \c -- cgit v0.12 From 5cb1ed45ba55dbc9752e0f6f47cc6d1525464646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 18 May 2009 13:01:52 +0200 Subject: QTemporaryFile: handle failures from QFSFileEngine::open(mode, fd) For now, this only happens if Append mode is requested and we're unable to seek to the end of the file. Theoretically, this could change in the future so it's better to err on the safe side. Reviewed-by: Thiago --- src/corelib/io/qtemporaryfile.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index e83d7e9..b6eff94 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -322,7 +322,6 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) qfilename += QLatin1String(".XXXXXX"); int suffixLength = qfilename.length() - (qfilename.lastIndexOf(QLatin1String("XXXXXX"), -1, Qt::CaseSensitive) + 6); - d->closeFileHandle = true; char *filename = qstrdup(qfilename.toLocal8Bit()); #ifndef Q_WS_WIN @@ -330,16 +329,19 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) if (fd != -1) { // First open the fd as an external file descriptor to // initialize the engine properly. - QFSFileEngine::open(openMode, fd); + if (QFSFileEngine::open(openMode, fd)) { - // Allow the engine to close the handle even if it's "external". - d->closeFileHandle = true; + // Allow the engine to close the handle even if it's "external". + d->closeFileHandle = true; - // Restore the file names (open() resets them). - d->filePath = QString::fromLocal8Bit(filename); //changed now! - d->nativeInitFileName(); - delete [] filename; - return true; + // Restore the file names (open() resets them). + d->filePath = QString::fromLocal8Bit(filename); //changed now! + d->nativeInitFileName(); + delete [] filename; + return true; + } + + QT_CLOSE(fd); } delete [] filename; setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno)); -- cgit v0.12 From f1793cbff8aa9b4adcb5fd511e495f7e96811e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 18 May 2009 14:58:44 +0200 Subject: Unconditionally open temporary files in ReadWrite mode Although QTemporaryFile hides QFile::open(OpenMode), this function is still available when accessing instance methods through the base class. Unconditionally setting ReadWrite allows the temporary file to be re-opened with different flags. Task-number: 248223 Reviewed-by: Thiago --- src/corelib/io/qtemporaryfile.cpp | 1 + tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index b6eff94..3f8f978 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -720,6 +720,7 @@ bool QTemporaryFile::open(OpenMode flags) return true; } + flags |= QIODevice::ReadWrite; if (QFile::open(flags)) { d->fileName = d->fileEngine->fileName(QAbstractFileEngine::DefaultName); return true; diff --git a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp index c6a43ff..26f5f40 100644 --- a/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/qtemporaryfile/tst_qtemporaryfile.cpp @@ -87,6 +87,8 @@ private slots: void stressTest(); void rename(); void renameFdLeak(); + void reOpenThroughQFile(); + public: }; @@ -424,5 +426,18 @@ void tst_QTemporaryFile::renameFdLeak() #endif } +void tst_QTemporaryFile::reOpenThroughQFile() +{ + QByteArray data("abcdefghij"); + + QTemporaryFile file; + QVERIFY(((QFile &)file).open(QIODevice::WriteOnly)); + QCOMPARE(file.write(data), (qint64)data.size()); + + file.close(); + QVERIFY(file.open()); + QCOMPARE(file.readAll(), data); +} + QTEST_MAIN(tst_QTemporaryFile) #include "tst_qtemporaryfile.moc" -- cgit v0.12 From 27369e563263e82a9c5747da54370eb0a225b3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 18 May 2009 18:40:03 +0200 Subject: QTemporaryFile: really (re)open file if it has been really closed... In some circumstances, the file descriptor in QTemporaryFile is actually closed and setOpenMode alone won't give us reOpen semantics. Added function to QTemporaryFileEngine that checks if we have open file handles. On open, if we currently hold no handles, re-open the file. Trying to open a new file while we hold open handles would lead to leaks, so added an assert there, to be on the safe side. Reviewed-by: Thiago --- src/corelib/io/qtemporaryfile.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 3f8f978..5e08ed8 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -294,6 +294,7 @@ public: QTemporaryFileEngine(const QString &file) : QFSFileEngine(file) { } ~QTemporaryFileEngine(); + bool isReallyOpen(); void setFileName(const QString &file); bool open(QIODevice::OpenMode flags); @@ -306,6 +307,21 @@ QTemporaryFileEngine::~QTemporaryFileEngine() QFSFileEngine::close(); } +bool QTemporaryFileEngine::isReallyOpen() +{ + Q_D(QFSFileEngine); + + if (!((0 == d->fh) && (-1 == d->fd) +#if defined Q_OS_WIN + && (INVALID_HANDLE_VALUE == d->fileHandle) +#endif + )) + return true; + + return false; + +} + void QTemporaryFileEngine::setFileName(const QString &file) { // Really close the file, so we don't leak @@ -316,6 +332,7 @@ void QTemporaryFileEngine::setFileName(const QString &file) bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) { Q_D(QFSFileEngine); + Q_ASSERT(!isReallyOpen()); QString qfilename = d->filePath; if(!qfilename.contains(QLatin1String("XXXXXX"))) @@ -716,8 +733,10 @@ bool QTemporaryFile::open(OpenMode flags) { Q_D(QTemporaryFile); if (!d->fileName.isEmpty()) { - setOpenMode(flags); - return true; + if (static_cast(fileEngine())->isReallyOpen()) { + setOpenMode(flags); + return true; + } } flags |= QIODevice::ReadWrite; -- cgit v0.12 From 84cbe8ffa4a7189c46efca9bb6387e80ab889c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Apr 2009 14:37:35 +0200 Subject: QTemporaryFile: there's no need to keep another pointer to the engine here Lifetime of the engine is already handled by the native engine. Reviewed-by: Thiago --- src/corelib/io/qtemporaryfile.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 5e08ed8..ec539d4 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -409,17 +409,14 @@ protected: bool autoRemove; QString templateName; - mutable QTemporaryFileEngine *fileEngine; }; -QTemporaryFilePrivate::QTemporaryFilePrivate() : autoRemove(true), fileEngine(0) +QTemporaryFilePrivate::QTemporaryFilePrivate() : autoRemove(true) { } QTemporaryFilePrivate::~QTemporaryFilePrivate() { - delete fileEngine; - fileEngine = 0; } //************* QTemporaryFile -- cgit v0.12 From 1044e75822270d702a3e9f14a87954321984c942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 18 May 2009 20:24:20 +0200 Subject: QTemporaryFileEngine now tracks if a fileName has been generated With recent changes to QTemporaryFile, allowing the file to be closed, the engine has to keep track of whether a fileName has already been generated, so we don't generate new files after the first one. If the file is closed but we already have a name for it, then just forward the call to the base file engine. Reviewed-by: Thiago --- src/corelib/io/qtemporaryfile.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index ec539d4..564ec59 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -291,7 +291,11 @@ class QTemporaryFileEngine : public QFSFileEngine { Q_DECLARE_PRIVATE(QFSFileEngine) public: - QTemporaryFileEngine(const QString &file) : QFSFileEngine(file) { } + QTemporaryFileEngine(const QString &file, bool fileIsTemplate = true) + : QFSFileEngine(file), filePathIsTemplate(fileIsTemplate) + { + } + ~QTemporaryFileEngine(); bool isReallyOpen(); @@ -300,6 +304,8 @@ public: bool open(QIODevice::OpenMode flags); bool remove(); bool close(); + + bool filePathIsTemplate; }; QTemporaryFileEngine::~QTemporaryFileEngine() @@ -334,6 +340,9 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) Q_D(QFSFileEngine); Q_ASSERT(!isReallyOpen()); + if (!filePathIsTemplate) + return QFSFileEngine::open(openMode); + QString qfilename = d->filePath; if(!qfilename.contains(QLatin1String("XXXXXX"))) qfilename += QLatin1String(".XXXXXX"); @@ -353,6 +362,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) // Restore the file names (open() resets them). d->filePath = QString::fromLocal8Bit(filename); //changed now! + filePathIsTemplate = false; d->nativeInitFileName(); delete [] filename; return true; @@ -370,6 +380,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) } d->filePath = QString::fromLocal8Bit(filename); + filePathIsTemplate = false; d->nativeInitFileName(); d->closeFileHandle = true; delete [] filename; @@ -714,8 +725,12 @@ QTemporaryFile *QTemporaryFile::createLocalFile(QFile &file) QAbstractFileEngine *QTemporaryFile::fileEngine() const { Q_D(const QTemporaryFile); - if(!d->fileEngine) - d->fileEngine = new QTemporaryFileEngine(d->templateName); + if(!d->fileEngine) { + if (d->fileName.isEmpty()) + d->fileEngine = new QTemporaryFileEngine(d->templateName); + else + d->fileEngine = new QTemporaryFileEngine(d->fileName, false); + } return d->fileEngine; } -- cgit v0.12 From ba706d2564f1181fa4cc596a46bb2a041c62c28f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 18 May 2009 13:08:04 +0200 Subject: QTemporaryFile: really close files before renaming This gets temporary file renaming working on Windows, without requiring block-copying. While we could #ifdef this behavior for Windows, it's preferrable to maintain consistency in the exposed interface. Reviewed-by: Thiago --- src/corelib/io/qtemporaryfile.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 564ec59..7c0b018 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -303,6 +303,7 @@ public: bool open(QIODevice::OpenMode flags); bool remove(); + bool rename(const QString &newName); bool close(); bool filePathIsTemplate; @@ -401,6 +402,12 @@ bool QTemporaryFileEngine::remove() return false; } +bool QTemporaryFileEngine::rename(const QString &newName) +{ + QFSFileEngine::close(); + return QFSFileEngine::rename(newName); +} + bool QTemporaryFileEngine::close() { // Don't close the file, just seek to the front. -- cgit v0.12 From a0396c8c68aca446e68434e516bd46d749093b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Mon, 18 May 2009 11:51:12 +0200 Subject: Reset openMode to NotOpen when returning false from QFile::open() When connecting to an open file descriptor, set the openMode in the file system engine, as is done for file handles. Reviewed-by: Thiago --- src/corelib/io/qfsfileengine.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 61ea7cc..1c8f0e9 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -312,6 +312,10 @@ bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh) if (ret == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(int(errno))); + + this->openMode = QIODevice::NotOpen; + this->fh = 0; + return false; } } @@ -335,6 +339,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd) if ((openMode & QFile::WriteOnly) && !(openMode & (QFile::ReadOnly | QFile::Append))) openMode |= QFile::Truncate; + d->openMode = openMode; d->lastFlushFailed = false; d->closeFileHandle = false; d->nativeFilePath.clear(); @@ -367,6 +372,10 @@ bool QFSFileEnginePrivate::openFd(QIODevice::OpenMode openMode, int fd) if (ret == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(int(errno))); + + this->openMode = QIODevice::NotOpen; + this->fd = -1; + return false; } } -- cgit v0.12 From 3ebbecd49d9e3cd8818634d5da5c7b1850190d54 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 22 May 2009 14:30:27 +0200 Subject: Make the default size of QMutexPool a prime number As pointed out by Olivier, this should allow for better distribution in the array. I also removed the unnecessary count member, since we can use QVarLengthArray.count() instead. --- src/corelib/thread/qmutexpool.cpp | 8 ++++---- src/corelib/thread/qmutexpool_p.h | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp index 77a3cca..0d7c890 100644 --- a/src/corelib/thread/qmutexpool.cpp +++ b/src/corelib/thread/qmutexpool.cpp @@ -96,9 +96,9 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (QMutex::Recursive)) QMutexPool is destructed. */ QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size) - : mutexes(size), count(size), recursionMode(recursionMode) + : mutexes(size), recursionMode(recursionMode) { - for (int index = 0; index < count; ++index) { + for (int index = 0; index < mutexes.count(); ++index) { mutexes[index] = 0; } } @@ -109,7 +109,7 @@ QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size) */ QMutexPool::~QMutexPool() { - for (int index = 0; index < count; ++index) { + for (int index = 0; index < mutexes.count(); ++index) { delete mutexes[index]; mutexes[index] = 0; } @@ -130,7 +130,7 @@ QMutexPool *QMutexPool::instance() QMutex *QMutexPool::get(const void *address) { Q_ASSERT_X(address != 0, "QMutexPool::get()", "'address' argument cannot be zero"); - int index = int((quintptr(address) >> (sizeof(address) >> 1)) % count); + int index = int((quintptr(address) >> (sizeof(address) >> 1)) % mutexes.count()); if (!mutexes[index]) { // mutex not created, create one diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h index 4c1e32c..30a16d4 100644 --- a/src/corelib/thread/qmutexpool_p.h +++ b/src/corelib/thread/qmutexpool_p.h @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QMutexPool { public: - explicit QMutexPool(QMutex::RecursionMode recursionMode = QMutex::NonRecursive, int size = 128); + explicit QMutexPool(QMutex::RecursionMode recursionMode = QMutex::NonRecursive, int size = 131); ~QMutexPool(); QMutex *get(const void *address); @@ -72,8 +72,7 @@ public: static QMutex *globalInstanceGet(const void *address); private: - QVarLengthArray, 128> mutexes; - int count; + QVarLengthArray, 131> mutexes; QMutex::RecursionMode recursionMode; }; -- cgit v0.12 From 96a5352b9460573a29dd31e884269e84187f6f88 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 22 May 2009 14:36:16 +0200 Subject: Fix compile issue Reviewed-by: Kent Hansen --- examples/animation/stickman/stickman.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/animation/stickman/stickman.pro b/examples/animation/stickman/stickman.pro index 956b49c..1dbbce9 100644 --- a/examples/animation/stickman/stickman.pro +++ b/examples/animation/stickman/stickman.pro @@ -10,6 +10,8 @@ SOURCES += main.cpp \ lifecycle.cpp \ graphicsview.cpp +INCLUDEPATH += $$PWD + include(editor/editor.pri) # install -- cgit v0.12 From 8b2a16bd7f434a159e34e93dbffc983927a0a143 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Fri, 22 May 2009 13:20:10 +0200 Subject: Fixed compilation with -qtnamespace Task-number: 254333 Reviewed-by: Andy Shaw --- src/corelib/io/qtemporaryfile.cpp | 4 +++- src/corelib/kernel/qsharedmemory_unix.cpp | 4 ++-- src/corelib/kernel/qsystemsemaphore_p.h | 4 ++-- src/corelib/kernel/qtranslator.cpp | 4 ++-- src/network/access/qhttp.cpp | 4 ++-- src/network/kernel/qnetworkproxy.cpp | 4 ++-- src/network/kernel/qurlinfo.cpp | 4 ++-- src/network/socket/qhttpsocketengine.cpp | 4 ++-- src/scripttools/debugging/qscriptenginedebugger.cpp | 13 ++++++++++--- 9 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 7c0b018..b4d8a48 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -766,6 +766,8 @@ bool QTemporaryFile::open(OpenMode flags) return false; } +QT_END_NAMESPACE + #endif // QT_NO_TEMPORARYFILE -QT_END_NAMESPACE + diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp index 487c653..61d56f4 100644 --- a/src/corelib/kernel/qsharedmemory_unix.cpp +++ b/src/corelib/kernel/qsharedmemory_unix.cpp @@ -49,10 +49,10 @@ #include -QT_BEGIN_NAMESPACE - #ifndef QT_NO_SHAREDMEMORY +QT_BEGIN_NAMESPACE + #include #include #include diff --git a/src/corelib/kernel/qsystemsemaphore_p.h b/src/corelib/kernel/qsystemsemaphore_p.h index 81d4f10..a4a7389 100644 --- a/src/corelib/kernel/qsystemsemaphore_p.h +++ b/src/corelib/kernel/qsystemsemaphore_p.h @@ -101,9 +101,9 @@ public: QSystemSemaphore::SystemSemaphoreError error; }; -#endif // QT_NO_SYSTEMSEMAPHORE +QT_END_NAMESPACE +#endif // QT_NO_SYSTEMSEMAPHORE -QT_END_NAMESPACE #endif // QSYSTEMSEMAPHORE_P_H diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 77d6599..3e4b467 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -819,6 +819,6 @@ bool QTranslator::isEmpty() const Use translate(\a context, \a sourceText, \a comment) instead. */ -#endif // QT_NO_TRANSLATION - QT_END_NAMESPACE + +#endif // QT_NO_TRANSLATION diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp index 7d14ab6..30befb3 100644 --- a/src/network/access/qhttp.cpp +++ b/src/network/access/qhttp.cpp @@ -64,10 +64,10 @@ # include "qtimer.h" #endif -QT_BEGIN_NAMESPACE - #ifndef QT_NO_HTTP +QT_BEGIN_NAMESPACE + class QHttpNormalRequest; class QHttpRequest { diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index 62bdfc7..fd3a85a 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -1258,6 +1258,6 @@ QList QNetworkProxyFactory::proxyForQuery(const QNetworkProxyQuer return globalNetworkProxy()->proxyForQuery(query); } -#endif // QT_NO_NETWORKPROXY - QT_END_NAMESPACE + +#endif // QT_NO_NETWORKPROXY diff --git a/src/network/kernel/qurlinfo.cpp b/src/network/kernel/qurlinfo.cpp index 255c9ea..d90c480 100644 --- a/src/network/kernel/qurlinfo.cpp +++ b/src/network/kernel/qurlinfo.cpp @@ -726,6 +726,6 @@ bool QUrlInfo::isValid() const return d != 0; } -#endif // QT_NO_URLINFO - QT_END_NAMESPACE + +#endif // QT_NO_URLINFO diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 540c443..5a2a746 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -768,6 +768,6 @@ QAbstractSocketEngine *QHttpSocketEngineHandler::createSocketEngine(int, QObject return 0; } -#endif - QT_END_NAMESPACE + +#endif diff --git a/src/scripttools/debugging/qscriptenginedebugger.cpp b/src/scripttools/debugging/qscriptenginedebugger.cpp index e35bd1d..0f8b600 100644 --- a/src/scripttools/debugging/qscriptenginedebugger.cpp +++ b/src/scripttools/debugging/qscriptenginedebugger.cpp @@ -63,16 +63,23 @@ #include #include +// this has to be outside the namespace +static void initScriptEngineDebuggerResources() +{ + Q_INIT_RESOURCE(scripttools_debugging); +} + +QT_BEGIN_NAMESPACE + class QtScriptDebuggerResourceInitializer { public: QtScriptDebuggerResourceInitializer() { - Q_INIT_RESOURCE(scripttools_debugging); + // call outside-the-namespace function + initScriptEngineDebuggerResources(); } }; -QT_BEGIN_NAMESPACE - /*! \since 4.5 \class QScriptEngineDebugger -- cgit v0.12 From df77e086585ad9f0fe5c7778643a76e5634ac7cd Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Fri, 22 May 2009 14:40:18 +0200 Subject: Fix QEasingCurve autotests Easing curve autotests was converting the easing(qreal) to int before, but this is a very rough comparison and was failing due to different conversions to int, so now we do a qFuzzyCompare. Reviewed-by: Thierry --- tests/auto/qeasingcurve/tst_qeasingcurve.cpp | 208 +++++++++++++++++++++++++-- 1 file changed, 193 insertions(+), 15 deletions(-) diff --git a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp index 8d42e5e..8fe15b1 100644 --- a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp @@ -179,28 +179,205 @@ void tst_QEasingCurve::propertyDefaults() } typedef QList IntList; +typedef QList RealList; Q_DECLARE_METATYPE(IntList) +Q_DECLARE_METATYPE(RealList) void tst_QEasingCurve::valueForProgress_data() { QTest::addColumn("type"); QTest::addColumn("at"); - QTest::addColumn("expected"); + QTest::addColumn("expected"); // automatically generated. // note that values are scaled from range [0,1] to range [0, 100] in order to store them as // integer values and avoid fp inaccuracies - QTest::newRow("Linear") << int(QEasingCurve::Linear) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.1 << 0.2 << 0.3 << 0.4 << 0.5 << 0.6 << 0.7 << 0.8 << 0.9 << 1); QTest::newRow("InQuad") << int(QEasingCurve::InQuad) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 1 << 4 << 9 << 16 << 25 << 36 << 48 << 64 << 81 << 100); + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.01 << 0.04 << 0.09 << 0.16 << 0.25 << 0.36 << 0.49 << 0.64 << 0.81 << 1); QTest::newRow("OutQuad") << int(QEasingCurve::OutQuad) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.19 << 0.36 << 0.51 << 0.64 << 0.75 << 0.84 << 0.91 << 0.96 << 0.99 << 1); + + QTest::newRow("InOutQuad") << int(QEasingCurve::InOutQuad) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.02 << 0.08 << 0.18 << 0.32 << 0.5 << 0.68 << 0.82 << 0.92 << 0.98 << 1); + + QTest::newRow("OutInQuad") << int(QEasingCurve::OutInQuad) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.18 << 0.32 << 0.42 << 0.48 << 0.5 << 0.52 << 0.58 << 0.68 << 0.82 << 1); + + QTest::newRow("InCubic") << int(QEasingCurve::InCubic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.001 << 0.008 << 0.027 << 0.064 << 0.125 << 0.216 << 0.343 << 0.512 << 0.729 << 1); + + QTest::newRow("OutCubic") << int(QEasingCurve::OutCubic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.271 << 0.488 << 0.657 << 0.784 << 0.875 << 0.936 << 0.973 << 0.992 << 0.999 << 1); + + QTest::newRow("InOutCubic") << int(QEasingCurve::InOutCubic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.004 << 0.032 << 0.108 << 0.256 << 0.5 << 0.744 << 0.892 << 0.968 << 0.996 << 1); + + QTest::newRow("OutInCubic") << int(QEasingCurve::OutInCubic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.244 << 0.392 << 0.468 << 0.496 << 0.5 << 0.504 << 0.532 << 0.608 << 0.756 << 1); + + QTest::newRow("InQuart") << int(QEasingCurve::InQuart) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.0001 << 0.0016 << 0.0081 << 0.0256 << 0.0625 << 0.1296 << 0.2401 << 0.4096 << 0.6561 << 1); + + QTest::newRow("OutQuart") << int(QEasingCurve::OutQuart) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.3439 << 0.5904 << 0.7599 << 0.8704 << 0.9375 << 0.9744 << 0.9919 << 0.9984 << 0.9999 << 1); + + QTest::newRow("InOutQuart") << int(QEasingCurve::InOutQuart) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.0008 << 0.0128 << 0.0648 << 0.2048 << 0.5 << 0.7952 << 0.9352 << 0.9872 << 0.9992 << 1); + + QTest::newRow("OutInQuart") << int(QEasingCurve::OutInQuart) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.2952 << 0.4352 << 0.4872 << 0.4992 << 0.5 << 0.5008 << 0.5128 << 0.5648 << 0.7048 << 1); + + QTest::newRow("InQuint") << int(QEasingCurve::InQuint) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 1e-05 << 0.00032 << 0.00243 << 0.01024 << 0.03125 << 0.07776 << 0.1681 << 0.3277 << 0.5905 << 1); + + QTest::newRow("OutQuint") << int(QEasingCurve::OutQuint) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.4095 << 0.6723 << 0.8319 << 0.9222 << 0.9688 << 0.9898 << 0.9976 << 0.9997 << 1 << 1); + + QTest::newRow("InOutQuint") << int(QEasingCurve::InOutQuint) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.00016 << 0.00512 << 0.03888 << 0.1638 << 0.5 << 0.8362 << 0.9611 << 0.9949 << 0.9998 << 1); + + QTest::newRow("OutInQuint") << int(QEasingCurve::OutInQuint) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.3362 << 0.4611 << 0.4949 << 0.4998 << 0.5 << 0.5002 << 0.5051 << 0.5389 << 0.6638 << 1); + + QTest::newRow("InSine") << int(QEasingCurve::InSine) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.01231 << 0.04894 << 0.109 << 0.191 << 0.2929 << 0.4122 << 0.546 << 0.691 << 0.8436 << 1); + + QTest::newRow("OutSine") << int(QEasingCurve::OutSine) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.1564 << 0.309 << 0.454 << 0.5878 << 0.7071 << 0.809 << 0.891 << 0.9511 << 0.9877 << 1); + + QTest::newRow("InOutSine") << int(QEasingCurve::InOutSine) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.02447 << 0.09549 << 0.2061 << 0.3455 << 0.5 << 0.6545 << 0.7939 << 0.9045 << 0.9755 << 1); + + QTest::newRow("OutInSine") << int(QEasingCurve::OutInSine) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.1545 << 0.2939 << 0.4045 << 0.4755 << 0.5 << 0.5245 << 0.5955 << 0.7061 << 0.8455 << 1); + + QTest::newRow("InExpo") << int(QEasingCurve::InExpo) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.0009531 << 0.002906 << 0.006812 << 0.01462 << 0.03025 << 0.0615 << 0.124 << 0.249 << 0.499 << 1); + + QTest::newRow("OutExpo") << int(QEasingCurve::OutExpo) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.5005 << 0.7507 << 0.8759 << 0.9384 << 0.9697 << 0.9854 << 0.9932 << 0.9971 << 0.999 << 1); + + QTest::newRow("InOutExpo") << int(QEasingCurve::InOutExpo) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.001453 << 0.007312 << 0.03075 << 0.1245 << 0.5002 << 0.8754 << 0.9692 << 0.9927 << 0.9985 << 1); + + QTest::newRow("OutInExpo") << int(QEasingCurve::OutInExpo) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.3754 << 0.4692 << 0.4927 << 0.4985 << 0.5 << 0.5015 << 0.5073 << 0.5308 << 0.6245 << 1); + + QTest::newRow("InCirc") << int(QEasingCurve::InCirc) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.005013 << 0.0202 << 0.04606 << 0.08348 << 0.134 << 0.2 << 0.2859 << 0.4 << 0.5641 << 1); + + QTest::newRow("OutCirc") << int(QEasingCurve::OutCirc) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.4359 << 0.6 << 0.7141 << 0.8 << 0.866 << 0.9165 << 0.9539 << 0.9798 << 0.995 << 1); + + QTest::newRow("InOutCirc") << int(QEasingCurve::InOutCirc) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.0101 << 0.04174 << 0.1 << 0.2 << 0.5 << 0.8 << 0.9 << 0.9583 << 0.9899 << 1); + + QTest::newRow("OutInCirc") << int(QEasingCurve::OutInCirc) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.3 << 0.4 << 0.4583 << 0.4899 << 0.5 << 0.5101 << 0.5417 << 0.6 << 0.7 << 1); + + QTest::newRow("InElastic") << int(QEasingCurve::InElastic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.001953 << -0.001953 << -0.003906 << 0.01562 << -0.01562 << -0.03125 << 0.125 << -0.125 << -0.25 << 1); + + QTest::newRow("OutElastic") << int(QEasingCurve::OutElastic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 1.25 << 1.125 << 0.875 << 1.031 << 1.016 << 0.9844 << 1.004 << 1.002 << 0.998 << 1); + + QTest::newRow("InOutElastic") << int(QEasingCurve::InOutElastic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << -0.0009766 << 0.007812 << -0.01563 << -0.0625 << 0.5 << 1.062 << 1.016 << 0.9922 << 1.001 << 1); + + QTest::newRow("OutInElastic") << int(QEasingCurve::OutInElastic) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.375 << 0.5625 << 0.4922 << 0.498 << 0.5 << 0.4961 << 0.5078 << 0.5313 << 0.25 << 1); + + QTest::newRow("InBack") << int(QEasingCurve::InBack) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << -0.01431 << -0.04645 << -0.0802 << -0.09935 << -0.0877 << -0.02903 << 0.09287 << 0.2942 << 0.5912 << 1); + + QTest::newRow("OutBack") << int(QEasingCurve::OutBack) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.4088 << 0.7058 << 0.9071 << 1.029 << 1.088 << 1.099 << 1.08 << 1.046 << 1.014 << 1); + + QTest::newRow("InOutBack") << int(QEasingCurve::InOutBack) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << -0.03752 << -0.09256 << -0.07883 << 0.08993 << 0.5 << 0.9101 << 1.079 << 1.093 << 1.038 << 1); + + QTest::newRow("OutInBack") << int(QEasingCurve::OutInBack) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.3529 << 0.5145 << 0.5497 << 0.5232 << 0.5 << 0.4768 << 0.4503 << 0.4855 << 0.6471 << 1); + + QTest::newRow("InBounce") << int(QEasingCurve::InBounce) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.01188 << 0.06 << 0.06937 << 0.2275 << 0.2344 << 0.09 << 0.3194 << 0.6975 << 0.9244 << 1); + + QTest::newRow("OutBounce") << int(QEasingCurve::OutBounce) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.07563 << 0.3025 << 0.6806 << 0.91 << 0.7656 << 0.7725 << 0.9306 << 0.94 << 0.9881 << 1); + + QTest::newRow("InOutBounce") << int(QEasingCurve::InOutBounce) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.03 << 0.1138 << 0.045 << 0.3488 << 0.5 << 0.6512 << 0.955 << 0.8862 << 0.97 << 1); + + QTest::newRow("OutInBounce") << int(QEasingCurve::OutInBounce) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.1513 << 0.41 << 0.2725 << 0.44 << 0.5 << 0.56 << 0.7275 << 0.59 << 0.8488 << 1); + + QTest::newRow("InCurve") << int(QEasingCurve::InCurve) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.02447 << 0.1059 << 0.2343 << 0.3727 << 0.5 << 0.6055 << 0.7 << 0.8 << 0.9 << 1); + + QTest::newRow("OutCurve") << int(QEasingCurve::OutCurve) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.1 << 0.2 << 0.3 << 0.3945 << 0.5 << 0.6273 << 0.7657 << 0.8941 << 0.9755 << 1); + + QTest::newRow("SineCurve") << int(QEasingCurve::SineCurve) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.09549 << 0.3455 << 0.6545 << 0.9045 << 1 << 0.9045 << 0.6545 << 0.3455 << 0.09549 << 0); + + QTest::newRow("CosineCurve") << int(QEasingCurve::CosineCurve) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0.5 << 0.7939 << 0.9755 << 0.9755 << 0.7939 << 0.5 << 0.2061 << 0.02447 << 0.02447 << 0.2061 << 0.5); + + /* + QTest::newRow("InQuad") << int(QEasingCurve::InQuad) + << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) + << (RealList() << 0 << 0.01 << 0.04 << 0.09 << 0.16 << 0.25 << 0.36 << 0.49 << 0.64 << 0.81 << 1); + QTest::newRow("OutQuad") << int(QEasingCurve::OutQuad) << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 19 << 36 << 51 << 64 << 75 << 84 << 90 << 96 << 99 << 100); + << (IntList() << 0 << 0.19 << 0.36 << 0.51 << 0.64 << 0.75 << 0.84 << 0.91 << 0.96 << 0.99 << 1); QTest::newRow("InOutQuad") << int(QEasingCurve::InOutQuad) << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) @@ -369,7 +546,7 @@ void tst_QEasingCurve::valueForProgress_data() QTest::newRow("CosineCurve") << int(QEasingCurve::CosineCurve) << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) << (IntList() << 50 << 79 << 97 << 97 << 79 << 50 << 20 << 2 << 2 << 20 << 49); - +*/ } @@ -389,12 +566,11 @@ void tst_QEasingCurve::valueForProgress() for (int t = 0; t <= 100; t+= 10) { qreal ease = curve.valueForProgress(t/qreal(100)); strInputs += QString::fromAscii(" << %1").arg(t); - strOutputs += QString::fromAscii(" << %1").arg(int(100*ease)); - + strOutputs += " << " + QString().setNum(ease, 'g', 4); } QString str = QString::fromAscii(" QTest::newRow(\"%1\") << int(QEasingCurve::%2)\n" - "\t\t << (IntList() %3)\n" - "\t\t << (IntList() %4);\n\n") + " << (IntList() %3)\n" + " << (RealList()%4);\n\n") .arg(strCurve) .arg(strCurve) .arg(strInputs) @@ -406,13 +582,15 @@ void tst_QEasingCurve::valueForProgress() #else QFETCH(int, type); QFETCH(IntList, at); - QFETCH(IntList, expected); + QFETCH(RealList, expected); QEasingCurve curve((QEasingCurve::Type)type); for (int i = 0; i < at.count(); ++i) { qreal ease = curve.valueForProgress(at.at(i)/qreal(100)); - int ex = expected.at(i); - QCOMPARE(int(100*ease), ex); + // converting ease to 4 precision qreal to match the generated samples + qreal easeConv = qreal(QString().setNum(ease, 'g', 4).toDouble()); + qreal ex = expected.at(i); + QVERIFY(qFuzzyCompare(easeConv, ex)); } #endif } -- cgit v0.12 From 289befd1bce5b47c48887d1fe23fb912b60a8e56 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 14:42:59 +0200 Subject: add some edge case tests for QStateMachine::start() & stop() --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 40c01bd..8354d03 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -2092,6 +2092,9 @@ void tst_QStateMachine::startAndStop() QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s1)); + QTest::ignoreMessage(QtWarningMsg, "QStateMachine::start(): already running"); + machine.start(); + machine.stop(); QTRY_COMPARE(machine.isRunning(), false); QTRY_COMPARE(stoppedSpy.count(), 1); @@ -2100,6 +2103,11 @@ void tst_QStateMachine::startAndStop() QCOMPARE(machine.configuration().count(), 1); QVERIFY(machine.configuration().contains(s1)); + + machine.start(); + machine.stop(); + QTRY_COMPARE(startedSpy.count(), 2); + QCOMPARE(stoppedSpy.count(), 2); } void tst_QStateMachine::targetStateWithNoParent() -- cgit v0.12 From fbab99479f83c4e51e4a28fd088a5f12f19dbf15 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 14:43:36 +0200 Subject: add qstatemachine autotest to auto.pro --- tests/auto/auto.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 38fa380..27e3c74 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -295,6 +295,7 @@ SUBDIRS += _networkselftest \ qstandarditem \ qstandarditemmodel \ qstate \ + qstatemachine \ qstatusbar \ qstl \ qstring \ -- cgit v0.12 From 751e0f1b70cb0c80e88f99e5137329d6f4b76562 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 22 May 2009 14:58:06 +0200 Subject: qdoc: Moved some qdoc comments into the .cpp file common to all packages. Task-number: 252494 --- src/corelib/io/qfsfileengine.cpp | 113 +++++++++++++++++++++++++++++++++++ src/corelib/io/qfsfileengine_win.cpp | 83 ------------------------- 2 files changed, 113 insertions(+), 83 deletions(-) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 61ea7cc..99c1909 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -868,6 +868,119 @@ bool QFSFileEngine::supportsExtension(Extension extension) const return false; } +/*! \fn bool QFSFileEngine::caseSensitive() const + Returns true for Windows, false for Unix. +*/ + +/*! \fn bool QFSFileEngine::copy(const QString ©Name) + + For windows, copy the file to file \a copyName. + + Not implemented for Unix. +*/ + +/*! \fn QString QFSFileEngine::currentPath(const QString &fileName) + For Unix, returns the current working directory for the file + engine. + + For Windows, returns the canonicalized form of the current path used + by the file engine for the drive specified by \a fileName. On + Windows, each drive has its own current directory, so a different + path is returned for file names that include different drive names + (e.g. A: or C:). + + \sa setCurrentPath() +*/ + +/*! \fn QFileInfoList QFSFileEngine::drives() + For Windows, returns the list of drives in the file system as a list + of QFileInfo objects. On unix, Mac OS X and Windows CE, only the + root path is returned. On Windows, this function returns all drives + (A:\, C:\, D:\, etc.). + + For Unix, the list contains just the root path "/". +*/ + +/*! \fn QString QFSFileEngine::fileName(FileName file) const + \reimp +*/ + +/*! \fn QDateTime QFSFileEngine::fileTime(FileTime time) const + \reimp +*/ + +/*! \fn QString QFSFileEngine::homePath() + Returns the home path of the current user. + + \sa rootPath() +*/ + +/*! \fn bool QFSFileEngine::isRelativePath() const + \reimp +*/ + +/*! \fn bool QFSFileEngine::link(const QString &newName) + + Creates a link from the file currently specified by fileName() to + \a newName. What a link is depends on the underlying filesystem + (be it a shortcut on Windows or a symbolic link on Unix). Returns + true if successful; otherwise returns false. +*/ + +/*! \fn bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const + \reimp +*/ + +/*! \fn uint QFSFileEngine::ownerId(FileOwner own) const + In Unix, if stat() is successful, the \c uid is returned if + \a own is the owner. Otherwise the \c gid is returned. If stat() + is unsuccessful, -2 is reuturned. + + For Windows, -2 is always returned. +*/ + +/*! \fn QString QFSFileEngine::owner() const + \reimp +*/ + +/*! \fn bool QFSFileEngine::remove() + \reimp +*/ + +/*! \fn bool QFSFileEngine::rename(const QString &newName) + \reimp +*/ + +/*! \fn bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const + \reimp +*/ + +/*! \fn QString QFSFileEngine::rootPath() + Returns the root path. + + \sa homePath() +*/ + +/*! \fn bool QFSFileEngine::setCurrentPath(const QString &path) + Sets the current path (e.g., for QDir), to \a path. Returns true if the + new path exists; otherwise this function does nothing, and returns false. + + \sa currentPath() +*/ + +/*! \fn bool QFSFileEngine::setPermissions(uint perms) + \reimp +*/ + +/*! \fn bool QFSFileEngine::setSize(qint64 size) + \reimp +*/ + +/*! \fn QString QFSFileEngine::tempPath() + Returns the temporary path (i.e., a path in which it is safe + to store temporary files). +*/ + QT_END_NAMESPACE #endif // QT_NO_FSFILEENGINE diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 63506c2..b22d6c7 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -946,9 +946,6 @@ bool QFSFileEnginePrivate::nativeIsSequential() const return false; } -/*! - \reimp -*/ bool QFSFileEngine::remove() { Q_D(QFSFileEngine); @@ -959,9 +956,6 @@ bool QFSFileEngine::remove() }); } -/*! - \reimp -*/ bool QFSFileEngine::copy(const QString ©Name) { Q_D(QFSFileEngine); @@ -974,9 +968,6 @@ bool QFSFileEngine::copy(const QString ©Name) }); } -/*! - \reimp -*/ bool QFSFileEngine::rename(const QString &newName) { Q_D(QFSFileEngine); @@ -1017,9 +1008,6 @@ static inline bool mkDir(const QString &path) }); } -/*! - \reimp -*/ static inline bool rmDir(const QString &path) { QT_WA({ @@ -1029,9 +1017,6 @@ static inline bool rmDir(const QString &path) }); } -/*! - \reimp -*/ static inline bool isDirPath(const QString &dirPath, bool *existed) { QString path = dirPath; @@ -1054,9 +1039,6 @@ static inline bool isDirPath(const QString &dirPath, bool *existed) return fileAttrib & FILE_ATTRIBUTE_DIRECTORY; } -/*! - \reimp -*/ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const { QString dirName = name; @@ -1097,9 +1079,6 @@ bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) con return mkDir(name); } -/*! - \reimp -*/ bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const { QString dirName = name; @@ -1120,20 +1099,11 @@ bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) co return rmDir(name); } -/*! - \reimp -*/ bool QFSFileEngine::caseSensitive() const { return false; } -/*! - Sets the current path (e.g., for QDir), to \a path. Returns true if the - new path exists; otherwise this function does nothing, and returns false. - - \sa currentPath() -*/ bool QFSFileEngine::setCurrentPath(const QString &path) { if (!QDir(path).exists()) @@ -1153,16 +1123,6 @@ bool QFSFileEngine::setCurrentPath(const QString &path) #endif } -/*! - Returns the canonicalized form of the current path used by the file - engine for the drive specified by \a fileName. - - On Windows, each drive has its own current directory, so a different - path is returned for file names that include different drive names - (e.g. A: or C:). - - \sa setCurrentPath() -*/ QString QFSFileEngine::currentPath(const QString &fileName) { #if !defined(Q_OS_WINCE) @@ -1219,11 +1179,6 @@ QString QFSFileEngine::currentPath(const QString &fileName) #endif } -/*! - Returns the home path of the current user. - - \sa rootPath() -*/ QString QFSFileEngine::homePath() { QString ret; @@ -1277,11 +1232,6 @@ QString QFSFileEngine::homePath() return QDir::fromNativeSeparators(ret); } -/*! - Returns the root path. - - \sa homePath() -*/ QString QFSFileEngine::rootPath() { #if defined(Q_OS_WINCE) @@ -1299,10 +1249,6 @@ QString QFSFileEngine::rootPath() return ret; } -/*! - Returns the temporary path (i.e., a path in which it is safe to store - temporary files). -*/ QString QFSFileEngine::tempPath() { QString ret; @@ -1330,11 +1276,6 @@ QString QFSFileEngine::tempPath() return ret; } -/*! - Returns the list of drives in the file system as a list of QFileInfo - objects. On unix, Mac OS X and Windows CE, only the root path is returned. - On Windows, this function returns all drives (A:\, C:\, D:\, etc.). -*/ QFileInfoList QFSFileEngine::drives() { QFileInfoList ret; @@ -1556,9 +1497,6 @@ QString QFSFileEnginePrivate::getLink() const return readLink(filePath); } -/*! - \reimp -*/ bool QFSFileEngine::link(const QString &newName) { #if !defined(Q_OS_WINCE) @@ -1816,9 +1754,6 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil return ret; } -/*! - \reimp -*/ QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); @@ -1912,9 +1847,6 @@ QString QFSFileEngine::fileName(FileName file) const return d->filePath; } -/*! - \reimp -*/ bool QFSFileEngine::isRelativePath() const { Q_D(const QFSFileEngine); @@ -1924,18 +1856,12 @@ bool QFSFileEngine::isRelativePath() const || (d->filePath.at(0) == QLatin1Char('/') && d->filePath.at(1) == QLatin1Char('/'))))); // drive, e.g. a: } -/*! - \reimp -*/ uint QFSFileEngine::ownerId(FileOwner /*own*/) const { static const uint nobodyID = (uint) -2; return nobodyID; } -/*! - \reimp -*/ QString QFSFileEngine::owner(FileOwner own) const { #if !defined(QT_NO_LIBRARY) @@ -1974,9 +1900,6 @@ QString QFSFileEngine::owner(FileOwner own) const return QString(QLatin1String("")); } -/*! - \reimp -*/ bool QFSFileEngine::setPermissions(uint perms) { Q_D(QFSFileEngine); @@ -2003,9 +1926,6 @@ bool QFSFileEngine::setPermissions(uint perms) return ret; } -/*! - \reimp -*/ bool QFSFileEngine::setSize(qint64 size) { Q_D(QFSFileEngine); @@ -2075,9 +1995,6 @@ static inline QDateTime fileTimeToQDateTime(const FILETIME *time) return ret; } -/*! - \reimp -*/ QDateTime QFSFileEngine::fileTime(FileTime time) const { Q_D(const QFSFileEngine); -- cgit v0.12 From 327d94ce8054718d0ce157604594e470e90d6cb4 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Fri, 22 May 2009 15:14:11 +0200 Subject: Fixes a potential crash when changing system palette with QGtkStyle The problem was that we installed an eventfilter regardless if the gtk symbols were defined or not. Instead we now initialize and check for the symbols before we install the filter. Task-number: 254342 Reviewed-by: ogoffart --- src/gui/styles/qgtkstyle.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index ca71da2..86653df 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -140,10 +140,7 @@ static const char * const dock_widget_restore_xpm[] = class QGtkStyleFilter : public QObject { public: - QGtkStyleFilter() { - qApp->installEventFilter(this); - } - + QGtkStyleFilter() {} private: bool eventFilter(QObject *obj, QEvent *e); }; @@ -167,7 +164,12 @@ class QGtkStylePrivate : public QCleanlooksStylePrivate public: QGtkStylePrivate() : QCleanlooksStylePrivate() - {} + { + QGtk::initGtkWidgets(); + if (QGtk::isThemeAvailable()) + qApp->installEventFilter(&filter); + + } QGtkStyleFilter filter; }; @@ -243,7 +245,6 @@ static QString uniqueName(const QString &key, const QStyleOption *option, const QGtkStyle::QGtkStyle() : QCleanlooksStyle(*new QGtkStylePrivate) { - QGtk::initGtkWidgets(); } /*! -- cgit v0.12 From 93106a55db7bd781cde889425912ebc4a277eb8f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Apr 2009 19:03:52 +0200 Subject: Fix syntax of the fcntl system call: this is not setsockopt Reviewed-By: Oswald Buddenhagen --- src/corelib/io/qfsfileengine_unix.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 18b92e2..459725c 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -273,9 +273,8 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len) int oldFlags = fcntl(QT_FILENO(fh), F_GETFL); for (int i = 0; i < 2; ++i) { // Unix: Make the underlying file descriptor non-blocking - int v = 1; if ((oldFlags & O_NONBLOCK) == 0) - fcntl(QT_FILENO(fh), F_SETFL, oldFlags | O_NONBLOCK, &v, sizeof(v)); + fcntl(QT_FILENO(fh), F_SETFL, oldFlags | O_NONBLOCK); // Cross platform stdlib read size_t read = 0; @@ -293,8 +292,7 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len) // Unix: Restore the blocking state of the underlying socket if ((oldFlags & O_NONBLOCK) == 0) { - int v = 1; - fcntl(QT_FILENO(fh), F_SETFL, oldFlags, &v, sizeof(v)); + fcntl(QT_FILENO(fh), F_SETFL, oldFlags); if (readBytes == 0) { int readByte = 0; do { @@ -311,8 +309,7 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len) } // Unix: Restore the blocking state of the underlying socket if ((oldFlags & O_NONBLOCK) == 0) { - int v = 1; - fcntl(QT_FILENO(fh), F_SETFL, oldFlags, &v, sizeof(v)); + fcntl(QT_FILENO(fh), F_SETFL, oldFlags); } if (readBytes == 0 && !feof(fh)) { // if we didn't read anything and we're not at EOF, it must be an error -- cgit v0.12 From b50f191132580771b470d5804a0a6616fbc1873f Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 15:30:52 +0200 Subject: Don't use the time() function; use QTime instead time() is not available on all platforms. --- examples/animation/moveblocks/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/animation/moveblocks/main.cpp b/examples/animation/moveblocks/main.cpp index b00485e..d315112 100644 --- a/examples/animation/moveblocks/main.cpp +++ b/examples/animation/moveblocks/main.cpp @@ -41,7 +41,6 @@ #include #include -#include class StateSwitchEvent: public QEvent { @@ -288,7 +287,7 @@ int main(int argc, char **argv) window.resize(300, 300); window.show(); - qsrand(time(0)); + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); return app.exec(); } -- cgit v0.12 From 74d54eeabcd648ee5100853299de8af5ac4b36f2 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 15:42:27 +0200 Subject: Make sure M_PI is defined It isn't on all platforms. --- examples/animation/stickman/stickman.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/animation/stickman/stickman.cpp b/examples/animation/stickman/stickman.cpp index e00ea41..a3b200c 100644 --- a/examples/animation/stickman/stickman.cpp +++ b/examples/animation/stickman/stickman.cpp @@ -48,6 +48,10 @@ #define _USE_MATH_DEFINES #include +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + static const int NodeCount = 16; static const qreal Coords[NodeCount * 2] = { 0.0, -150.0, // head, #0 -- cgit v0.12 From 049135667302482af66eeaf9a2323d5ee1551132 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Fri, 22 May 2009 15:42:31 +0200 Subject: Doc - updating the screenshot Reviewed-By: TrustMe --- doc/src/images/inputdialogs.png | Bin 4244 -> 30369 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/src/images/inputdialogs.png b/doc/src/images/inputdialogs.png index 135c2f6..8bda185 100644 Binary files a/doc/src/images/inputdialogs.png and b/doc/src/images/inputdialogs.png differ -- cgit v0.12 From 24d798694b794732240e85fa65b958b8c97cbef5 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 16:19:21 +0200 Subject: make sure event transition is correctly unregistered/re-registered When the eventType or eventObject is changed while the state is active, the transition needs to be unregistered _before_ either property is changed, only _then_ can it be re-registered. --- src/corelib/statemachine/qeventtransition.cpp | 29 ++++++++++++++------------ src/corelib/statemachine/qeventtransition_p.h | 3 ++- tests/auto/qstatemachine/tst_qstatemachine.cpp | 13 ++++++++++++ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/corelib/statemachine/qeventtransition.cpp b/src/corelib/statemachine/qeventtransition.cpp index 74eb577..f25d821 100644 --- a/src/corelib/statemachine/qeventtransition.cpp +++ b/src/corelib/statemachine/qeventtransition.cpp @@ -111,19 +111,20 @@ QEventTransitionPrivate *QEventTransitionPrivate::get(QEventTransition *q) return q->d_func(); } -void QEventTransitionPrivate::invalidate() +void QEventTransitionPrivate::unregister() { Q_Q(QEventTransition); - if (registered) { - QState *source = sourceState(); - QStatePrivate *source_d = QStatePrivate::get(source); - QStateMachinePrivate *mach = QStateMachinePrivate::get(source_d->machine()); - if (mach) { - mach->unregisterEventTransition(q); - if (mach->configuration.contains(source)) - mach->registerEventTransition(q); - } - } + if (!registered || !machine()) + return; + QStateMachinePrivate::get(machine())->unregisterEventTransition(q); +} + +void QEventTransitionPrivate::maybeRegister() +{ + Q_Q(QEventTransition); + if (!machine() || !machine()->configuration().contains(sourceState())) + return; + QStateMachinePrivate::get(machine())->registerEventTransition(q); } /*! @@ -223,8 +224,9 @@ void QEventTransition::setEventType(QEvent::Type type) Q_D(QEventTransition); if (d->eventType == type) return; + d->unregister(); d->eventType = type; - d->invalidate(); + d->maybeRegister(); } /*! @@ -245,8 +247,9 @@ void QEventTransition::setEventObject(QObject *object) Q_D(QEventTransition); if (d->object == object) return; + d->unregister(); d->object = object; - d->invalidate(); + d->maybeRegister(); } /*! diff --git a/src/corelib/statemachine/qeventtransition_p.h b/src/corelib/statemachine/qeventtransition_p.h index fca8c0d..600cec0 100644 --- a/src/corelib/statemachine/qeventtransition_p.h +++ b/src/corelib/statemachine/qeventtransition_p.h @@ -66,7 +66,8 @@ public: static QEventTransitionPrivate *get(QEventTransition *q); - void invalidate(); + void unregister(); + void maybeRegister(); bool registered; QObject *object; diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 8354d03..a5070cb 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -1836,6 +1836,19 @@ void tst_QStateMachine::eventTransitions() QCoreApplication::processEvents(); QTest::mouseRelease(&button, Qt::LeftButton); QTRY_COMPARE(finishedSpy.count(), 2); + + machine.start(); + QCoreApplication::processEvents(); + trans->setEventType(QEvent::MouseButtonPress); + QTest::mousePress(&button, Qt::LeftButton); + QTRY_COMPARE(finishedSpy.count(), 3); + + QPushButton button2; + machine.start(); + QCoreApplication::processEvents(); + trans->setEventObject(&button2); + QTest::mousePress(&button2, Qt::LeftButton); + QTRY_COMPARE(finishedSpy.count(), 4); } for (int x = 0; x < 3; ++x) { QStateMachine machine; -- cgit v0.12 From 1602820bb4d2b13f843594194ace2186f4f72806 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 16:31:40 +0200 Subject: make sure signal transition is correctly unregistered/re-registered When the signal or senderObject is changed while the state is active, the transition needs to be unregistered _before_ either property is changed, only _then_ can it be re-registered. --- src/corelib/statemachine/qsignaltransition.cpp | 29 +++++++++++---------- src/corelib/statemachine/qsignaltransition_p.h | 3 ++- tests/auto/qstatemachine/tst_qstatemachine.cpp | 35 ++++++++++++++++++++------ 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp index 4caa917..9ffcb9c 100644 --- a/src/corelib/statemachine/qsignaltransition.cpp +++ b/src/corelib/statemachine/qsignaltransition.cpp @@ -118,19 +118,20 @@ QSignalTransitionPrivate *QSignalTransitionPrivate::get(QSignalTransition *q) return q->d_func(); } -void QSignalTransitionPrivate::invalidate() +void QSignalTransitionPrivate::unregister() { Q_Q(QSignalTransition); - if (signalIndex != -1) { - QState *source = sourceState(); - QStatePrivate *source_d = QStatePrivate::get(source); - QStateMachinePrivate *mach = QStateMachinePrivate::get(source_d->machine()); - if (mach) { - mach->unregisterSignalTransition(q); - if (mach->configuration.contains(source)) - mach->registerSignalTransition(q); - } - } + if ((signalIndex == -1) || !machine()) + return; + QStateMachinePrivate::get(machine())->unregisterSignalTransition(q); +} + +void QSignalTransitionPrivate::maybeRegister() +{ + Q_Q(QSignalTransition); + if (!machine() || !machine()->configuration().contains(sourceState())) + return; + QStateMachinePrivate::get(machine())->registerSignalTransition(q); } /*! @@ -193,8 +194,9 @@ void QSignalTransition::setSenderObject(QObject *sender) Q_D(QSignalTransition); if (sender == d->sender) return; + d->unregister(); d->sender = sender; - d->invalidate(); + d->maybeRegister(); } /*! @@ -214,8 +216,9 @@ void QSignalTransition::setSignal(const QByteArray &signal) Q_D(QSignalTransition); if (signal == d->signal) return; + d->unregister(); d->signal = signal; - d->invalidate(); + d->maybeRegister(); } /*! diff --git a/src/corelib/statemachine/qsignaltransition_p.h b/src/corelib/statemachine/qsignaltransition_p.h index a23e58c..339de63 100644 --- a/src/corelib/statemachine/qsignaltransition_p.h +++ b/src/corelib/statemachine/qsignaltransition_p.h @@ -66,7 +66,8 @@ public: static QSignalTransitionPrivate *get(QSignalTransition *q); - void invalidate(); + void unregister(); + void maybeRegister(); QObject *sender; QByteArray signal; diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index a5070cb..6de7e1a 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -1666,14 +1666,12 @@ void tst_QStateMachine::signalTransitions() QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: no such signal SignalEmitter::noSuchSignal()"); QCOMPARE(s0->addTransition(&emitter, SIGNAL(noSuchSignal()), s1), (QObject*)0); - { - QSignalTransition *trans = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); - QVERIFY(trans != 0); - QCOMPARE(trans->sourceState(), s0); - QCOMPARE(trans->targetState(), (QAbstractState*)s1); - QCOMPARE(trans->senderObject(), (QObject*)&emitter); - QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); - } + QSignalTransition *trans = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); + QVERIFY(trans != 0); + QCOMPARE(trans->sourceState(), s0); + QCOMPARE(trans->targetState(), (QAbstractState*)s1); + QCOMPARE(trans->senderObject(), (QObject*)&emitter); + QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); QSignalSpy finishedSpy(&machine, SIGNAL(finished())); machine.setInitialState(s0); @@ -1685,6 +1683,27 @@ void tst_QStateMachine::signalTransitions() QTRY_COMPARE(finishedSpy.count(), 1); emitter.emitSignalWithNoArg(); + + trans->setSignal(SIGNAL(signalWithIntArg(int))); + QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithIntArg(int)))); + machine.start(); + QCoreApplication::processEvents(); + emitter.emitSignalWithIntArg(123); + QTRY_COMPARE(finishedSpy.count(), 2); + + machine.start(); + QCoreApplication::processEvents(); + trans->setSignal(SIGNAL(signalWithNoArg())); + QCOMPARE(trans->signal(), QByteArray(SIGNAL(signalWithNoArg()))); + emitter.emitSignalWithNoArg(); + QTRY_COMPARE(finishedSpy.count(), 3); + + SignalEmitter emitter2; + machine.start(); + QCoreApplication::processEvents(); + trans->setSenderObject(&emitter2); + emitter2.emitSignalWithNoArg(); + QTRY_COMPARE(finishedSpy.count(), 4); } { QStateMachine machine; -- cgit v0.12 From c6d683eefc76b6bb5be465533c5fead97fedcdc4 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 22 May 2009 16:40:58 +0200 Subject: Fix compilation on Solaris for animation API. Reviewed-by: thierry --- src/corelib/animation/qvariantanimation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h index 5b90930..3ae172f 100644 --- a/src/corelib/animation/qvariantanimation.h +++ b/src/corelib/animation/qvariantanimation.h @@ -117,7 +117,7 @@ private: }; template -static void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) { +void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) { QVariantAnimation::registerInterpolator(reinterpret_cast(func), qMetaTypeId()); } -- cgit v0.12 From d19ed9d337b79a3dc88690db66a8ea8d4482cddd Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 16:41:41 +0200 Subject: add tests for multiple signal/event transitions from same source --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 68 ++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 6de7e1a..c01d077 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -1815,6 +1815,43 @@ void tst_QStateMachine::signalTransitions() QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); } + // multiple signal transitions from same source + { + QStateMachine machine; + SignalEmitter emitter; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); + QFinalState *s2 = new QFinalState(machine.rootState()); + s0->addTransition(&emitter, SIGNAL(signalWithIntArg(int)), s2); + QFinalState *s3 = new QFinalState(machine.rootState()); + s0->addTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s3); + + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + emitter.emitSignalWithNoArg(); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.start(); + QTRY_COMPARE(startedSpy.count(), 2); + emitter.emitSignalWithIntArg(123); + QTRY_COMPARE(finishedSpy.count(), 2); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + + machine.start(); + QTRY_COMPARE(startedSpy.count(), 3); + emitter.emitSignalWithStringArg("hello"); + QTRY_COMPARE(finishedSpy.count(), 3); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s3)); + } } void tst_QStateMachine::eventTransitions() @@ -2024,6 +2061,37 @@ void tst_QStateMachine::eventTransitions() QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s1)); } + // multiple event transitions from same source + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + QFinalState *s2 = new QFinalState(machine.rootState()); + QEventTransition *t0 = new QEventTransition(&button, QEvent::MouseButtonPress); + t0->setTargetState(s1); + s0->addTransition(t0); + QEventTransition *t1 = new QEventTransition(&button, QEvent::MouseButtonRelease); + t1->setTargetState(s2); + s0->addTransition(t1); + + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.setInitialState(s0); + + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + QTest::mousePress(&button, Qt::LeftButton); + QTRY_COMPARE(finishedSpy.count(), 1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + machine.start(); + QTRY_COMPARE(startedSpy.count(), 2); + QTest::mouseRelease(&button, Qt::LeftButton); + QTRY_COMPARE(finishedSpy.count(), 2); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + } } void tst_QStateMachine::historyStates() -- cgit v0.12 From 5ae1ccd2b12fcbc55fa2d14c39d8da3f4440a11d Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 16:50:03 +0200 Subject: test what happens when changing to an invalid signal while state is active --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index c01d077..76c5de1 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -1704,6 +1704,12 @@ void tst_QStateMachine::signalTransitions() trans->setSenderObject(&emitter2); emitter2.emitSignalWithNoArg(); QTRY_COMPARE(finishedSpy.count(), 4); + + machine.start(); + QCoreApplication::processEvents(); + QTest::ignoreMessage(QtWarningMsg, "QSignalTransition: no such signal: SignalEmitter::noSuchSignal()"); + trans->setSignal(SIGNAL(noSuchSignal())); + QCOMPARE(trans->signal(), QByteArray(SIGNAL(noSuchSignal()))); } { QStateMachine machine; -- cgit v0.12 From fc7a43cceba63b79a40183334ab97527483113e3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 22 May 2009 16:55:28 +0200 Subject: Fix compilation breakage on Windows caused by 6c1d7e57. On Windows, QT_NO_IPV6 isn't defined, but the necessary includes were missing. So #include winsock2.h and also use our own structures. Reviewed-By: Trust Me --- src/network/socket/qnativesocketengine_p.h | 36 +++++++++++++++++++++---- src/network/socket/qnativesocketengine_unix.cpp | 2 +- src/network/socket/qnativesocketengine_win.cpp | 35 ------------------------ 3 files changed, 32 insertions(+), 41 deletions(-) diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h index 825c333..eb031d3 100644 --- a/src/network/socket/qnativesocketengine_p.h +++ b/src/network/socket/qnativesocketengine_p.h @@ -56,7 +56,9 @@ #include "QtNetwork/qhostaddress.h" #include "private/qabstractsocketengine_p.h" #ifndef Q_OS_WIN -#include "qplatformdefs.h" +# include "qplatformdefs.h" +#else +# include #endif QT_BEGIN_NAMESPACE @@ -90,13 +92,37 @@ static inline int qt_socket_socket(int domain, int type, int protocol) #endif +// Use our own defines and structs which we know are correct +# define QT_SS_MAXSIZE 128 +# define QT_SS_ALIGNSIZE (sizeof(qint64)) +# define QT_SS_PAD1SIZE (QT_SS_ALIGNSIZE - sizeof (short)) +# define QT_SS_PAD2SIZE (QT_SS_MAXSIZE - (sizeof (short) + QT_SS_PAD1SIZE + QT_SS_ALIGNSIZE)) +struct qt_sockaddr_storage { + short ss_family; + char __ss_pad1[QT_SS_PAD1SIZE]; + qint64 __ss_align; + char __ss_pad2[QT_SS_PAD2SIZE]; +}; + +// sockaddr_in6 size changed between old and new SDK +// Only the new version is the correct one, so always +// use this structure. +struct qt_in6_addr { + quint8 qt_s6_addr[16]; +}; +struct qt_sockaddr_in6 { + short sin6_family; /* AF_INET6 */ + quint16 sin6_port; /* Transport level port number */ + quint32 sin6_flowinfo; /* IPv6 flow information */ + struct qt_in6_addr sin6_addr; /* IPv6 address */ + quint32 sin6_scope_id; /* set of interfaces for a scope */ +}; + union qt_sockaddr { sockaddr a; sockaddr_in a4; -#if !defined(QT_NO_IPV6) - sockaddr_in6 a6; -#endif - sockaddr_storage storage; + qt_sockaddr_in6 a6; + qt_sockaddr_storage storage; }; class QNativeSocketEnginePrivate; diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 2b11e8e..75b5a64 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -119,7 +119,7 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po #if !defined(QT_NO_IPV6) if (s->a.sa_family == AF_INET6) { Q_IPV6ADDR tmp; - memcpy(&tmp, &s->a6.sin6_addr.s6_addr, sizeof(tmp)); + memcpy(&tmp, &s->a6.sin6_addr, sizeof(tmp)); if (addr) { QHostAddress tmpAddress; tmpAddress.setAddress(tmp); diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index d140be2..b08d7b0 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -149,41 +149,6 @@ static QByteArray qt_prettyDebug(const char *data, int len, int maxLength) #endif -#if !defined (QT_NO_IPV6) - -// Use our own defines and structs which we know are correct -# define QT_SS_MAXSIZE 128 -# define QT_SS_ALIGNSIZE (sizeof(__int64)) -# define QT_SS_PAD1SIZE (QT_SS_ALIGNSIZE - sizeof (short)) -# define QT_SS_PAD2SIZE (QT_SS_MAXSIZE - (sizeof (short) + QT_SS_PAD1SIZE + QT_SS_ALIGNSIZE)) -struct qt_sockaddr_storage { - short ss_family; - char __ss_pad1[QT_SS_PAD1SIZE]; - __int64 __ss_align; - char __ss_pad2[QT_SS_PAD2SIZE]; -}; - -// sockaddr_in6 size changed between old and new SDK -// Only the new version is the correct one, so always -// use this structure. -struct qt_in6_addr { - u_char qt_s6_addr[16]; -}; -typedef struct { - short sin6_family; /* AF_INET6 */ - u_short sin6_port; /* Transport level port number */ - u_long sin6_flowinfo; /* IPv6 flow information */ - struct qt_in6_addr sin6_addr; /* IPv6 address */ - u_long sin6_scope_id; /* set of interfaces for a scope */ -} qt_sockaddr_in6; - -#else - -typedef void * qt_sockaddr_in6 ; - - -#endif - #ifndef AF_INET6 #define AF_INET6 23 /* Internetwork Version 6 */ #endif -- cgit v0.12 From 73f953dce2c184c36476c3412880a7aee10ef638 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Fri, 22 May 2009 17:22:05 +0200 Subject: add various tests Trying to get coverage up to 100% --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 104 ++++++++++++++++++++----- 1 file changed, 86 insertions(+), 18 deletions(-) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 76c5de1..768a683 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -81,6 +81,24 @@ static int globalTick; QCoreApplication::exec(); \ } +class SignalEmitter : public QObject +{ +Q_OBJECT + public: + SignalEmitter(QObject *parent = 0) + : QObject(parent) {} + void emitSignalWithNoArg() + { emit signalWithNoArg(); } + void emitSignalWithIntArg(int arg) + { emit signalWithIntArg(arg); } + void emitSignalWithStringArg(const QString &arg) + { emit signalWithStringArg(arg); } +Q_SIGNALS: + void signalWithNoArg(); + void signalWithIntArg(int); + void signalWithStringArg(const QString &); +}; + class tst_QStateMachine : public QObject { Q_OBJECT @@ -1045,6 +1063,20 @@ void tst_QStateMachine::addAndRemoveState() QTest::ignoreMessage(QtWarningMsg, "QStateMachine::removeState: cannot remove null state"); machine.removeState(0); + { + QStateMachine machine2; + { + char warning[256]; + sprintf(warning, "QStateMachine::removeState: state %p's machine (%p) is different from this machine (%p)", + machine2.rootState(), &machine2, &machine); + QTest::ignoreMessage(QtWarningMsg, warning); + machine.removeState(machine2.rootState()); + } + // ### check this behavior + machine.addState(machine2.rootState()); + QCOMPARE(machine2.rootState()->parent(), (QObject*)machine.rootState()); + } + delete s1; delete s2; // ### how to deal with this? @@ -1397,6 +1429,44 @@ void tst_QStateMachine::assignPropertyWithAnimation() QCOMPARE(obj.property("foo").toInt(), 321); QCOMPARE(obj.property("bar").toInt(), 789); } + // Aborted animation + { + QStateMachine machine; + SignalEmitter emitter; + QObject obj; + obj.setProperty("foo", 321); + obj.setProperty("bar", 654); + QState *group = new QState(machine.rootState()); + QState *s1 = new QState(group); + group->setInitialState(s1); + s1->assignProperty(&obj, "foo", 123); + QState *s2 = new QState(group); + s2->assignProperty(&obj, "foo", 456); + s2->assignProperty(&obj, "bar", 789); + QAbstractTransition *trans = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s2); + QPropertyAnimation anim(&obj, "foo"); + anim.setDuration(8000); + trans->addAnimation(&anim); + QPropertyAnimation anim2(&obj, "bar"); + anim2.setDuration(8000); + trans->addAnimation(&anim2); + QState *s3 = new QState(group); + s3->assignProperty(&obj, "foo", 911); + s2->addTransition(&emitter, SIGNAL(signalWithNoArg()), s3); + + machine.setInitialState(group); + machine.start(); + QTRY_COMPARE(machine.configuration().contains(s1), true); + QSignalSpy polishedSpy(s2, SIGNAL(polished())); + emitter.emitSignalWithNoArg(); + QTRY_COMPARE(machine.configuration().contains(s2), true); + QVERIFY(polishedSpy.isEmpty()); + emitter.emitSignalWithNoArg(); // will cause animations from s1-->s2 to abort + QTRY_COMPARE(machine.configuration().contains(s3), true); + QVERIFY(polishedSpy.isEmpty()); + QCOMPARE(obj.property("foo").toInt(), 911); + QCOMPARE(obj.property("bar").toInt(), 789); + } } struct StringEvent : public QEvent @@ -1606,24 +1676,6 @@ void tst_QStateMachine::allSourceToTargetConfigurations() QTRY_COMPARE(finishedSpy.count(), 1); } -class SignalEmitter : public QObject -{ -Q_OBJECT - public: - SignalEmitter(QObject *parent = 0) - : QObject(parent) {} - void emitSignalWithNoArg() - { emit signalWithNoArg(); } - void emitSignalWithIntArg(int arg) - { emit signalWithIntArg(arg); } - void emitSignalWithStringArg(const QString &arg) - { emit signalWithStringArg(arg); } -Q_SIGNALS: - void signalWithNoArg(); - void signalWithIntArg(int); - void signalWithStringArg(const QString &); -}; - class TestSignalTransition : public QSignalTransition { public: @@ -2098,6 +2150,22 @@ void tst_QStateMachine::eventTransitions() QCOMPARE(machine.configuration().size(), 1); QVERIFY(machine.configuration().contains(s2)); } + // custom event + { + QStateMachine machine; + QState *s0 = new QState(machine.rootState()); + QFinalState *s1 = new QFinalState(machine.rootState()); + + QEventTransition *trans = new QEventTransition(&button, QEvent::Type(QEvent::User+1)); + trans->setTargetState(s1); + s0->addTransition(trans); + + QSignalSpy startedSpy(&machine, SIGNAL(started())); + machine.setInitialState(s0); + machine.start(); + QTest::ignoreMessage(QtWarningMsg, "QObject event transitions are not supported for custom types"); + QTRY_COMPARE(startedSpy.count(), 1); + } } void tst_QStateMachine::historyStates() -- cgit v0.12 From 701bdcbc8b7751834f6d24844bcb91a23cbdc409 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 22 May 2009 15:48:23 +0200 Subject: Pressing enter in a QPlainTextEdit embedded on a itemview should insert a newline Do the same special case as for QTextEdit (yes, this is a pitty that we have special cases like that Reviewed-by: Thierry Task-number: 252532 --- src/gui/itemviews/qitemdelegate.cpp | 3 +- src/gui/itemviews/qstyleditemdelegate.cpp | 3 +- tests/auto/qitemdelegate/tst_qitemdelegate.cpp | 78 ++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 3b7eb2d..a748199 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -1194,7 +1195,7 @@ bool QItemDelegate::eventFilter(QObject *object, QEvent *event) case Qt::Key_Enter: case Qt::Key_Return: #ifndef QT_NO_TEXTEDIT - if (qobject_cast(editor)) + if (qobject_cast(editor) || qobject_cast(editor)) return false; // don't filter enter key events for QTextEdit // We want the editor to be able to process the key press // before committing the data (e.g. so it can do diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index be0971b..7f2c8ed 100644 --- a/src/gui/itemviews/qstyleditemdelegate.cpp +++ b/src/gui/itemviews/qstyleditemdelegate.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -646,7 +647,7 @@ bool QStyledItemDelegate::eventFilter(QObject *object, QEvent *event) case Qt::Key_Enter: case Qt::Key_Return: #ifndef QT_NO_TEXTEDIT - if (qobject_cast(editor)) + if (qobject_cast(editor) || qobject_cast(editor)) return false; // don't filter enter key events for QTextEdit // We want the editor to be able to process the key press // before committing the data (e.g. so it can do diff --git a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp index 27741e0..615ac01 100644 --- a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp @@ -59,6 +59,8 @@ #include #include +#include +#include Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint) @@ -226,6 +228,8 @@ private slots: void decoration(); void editorEvent_data(); void editorEvent(); + void enterKey_data(); + void enterKey(); }; @@ -1048,6 +1052,80 @@ void tst_QItemDelegate::editorEvent() QCOMPARE(index.data(Qt::CheckStateRole).toInt(), expectedCheckState); } +void tst_QItemDelegate::enterKey_data() +{ + QTest::addColumn("widget"); + QTest::addColumn("key"); + QTest::addColumn("expectedFocus"); + + QTest::newRow("lineedit enter") << 1 << int(Qt::Key_Enter) << false; + QTest::newRow("textedit enter") << 2 << int(Qt::Key_Enter) << true; + QTest::newRow("plaintextedit enter") << 3 << int(Qt::Key_Enter) << true; + QTest::newRow("plaintextedit return") << 3 << int(Qt::Key_Return) << true; + QTest::newRow("plaintextedit tab") << 3 << int(Qt::Key_Tab) << false; + QTest::newRow("lineedit tab") << 1 << int(Qt::Key_Tab) << false; +} + +void tst_QItemDelegate::enterKey() +{ + QFETCH(int, widget); + QFETCH(int, key); + QFETCH(bool, expectedFocus); + + QStandardItemModel model; + model.appendRow(new QStandardItem()); + + QListView view; + view.setModel(&model); + view.show(); + QApplication::setActiveWindow(&view); + view.setFocus(); + QTest::qWait(30); + + struct TestDelegate : public QItemDelegate + { + int widgetType; + virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) const + { + QWidget *editor = 0; + switch(widgetType) { + case 1: + editor = new QLineEdit(parent); + break; + case 2: + editor = new QTextEdit(parent); + break; + case 3: + editor = new QPlainTextEdit(parent); + break; + } + editor->setObjectName(QString::fromLatin1("TheEditor")); + return editor; + } + } delegate; + + delegate.widgetType = widget; + + view.setItemDelegate(&delegate); + QModelIndex index = model.index(0, 0); + view.setCurrentIndex(index); // the editor will only selectAll on the current index + view.edit(index); + QTest::qWait(30); + + QList lineEditors = qFindChildren(view.viewport(), QString::fromLatin1("TheEditor")); + QCOMPARE(lineEditors.count(), 1); + + QWidget *editor = lineEditors.at(0); + QCOMPARE(editor->hasFocus(), true); + + QTest::keyClick(editor, Qt::Key(key)); + QApplication::processEvents(); + + QCOMPARE(editor->hasFocus(), expectedFocus); +} + + + // ### _not_ covered: // editing with a custom editor factory -- cgit v0.12 From 37b0711beb909f3d0bd6f2420aa44bc49e786cd5 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Fri, 22 May 2009 17:47:01 +0200 Subject: Fix build on Solaris for qHash function in QPixmapCache. Reviewed-by:thierry --- src/gui/image/qpixmapcache.cpp | 2 +- src/gui/image/qpixmapcache_p.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 810ce65..eb1ebd1 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -183,7 +183,7 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "qpixmapcache.moc" QT_END_INCLUDE_NAMESPACE -static uint qHash(const QPixmapCache::Key &k) +uint qHash(const QPixmapCache::Key &k) { return qHash(QPMCache::get(k)->key); } diff --git a/src/gui/image/qpixmapcache_p.h b/src/gui/image/qpixmapcache_p.h index 5aa6eaf..a35e0d2 100644 --- a/src/gui/image/qpixmapcache_p.h +++ b/src/gui/image/qpixmapcache_p.h @@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE +uint qHash(const QPixmapCache::Key &k); + class QPixmapCache::KeyData { public: -- cgit v0.12 From bbf3361d42c85d9da712e0261ecc87d62a29e403 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 22 May 2009 18:13:46 +0200 Subject: Remove IRIX code. IRIX is no longer supported, so I won't bother fixing this part of the code. Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess_unix.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index c39588c..b06e217 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -385,17 +385,10 @@ static void qt_create_pipe(int *pipe) qt_native_close(pipe[0]); if (pipe[1] != -1) qt_native_close(pipe[1]); -#ifdef Q_OS_IRIX - if (::socketpair(AF_UNIX, SOCK_STREAM, 0, pipe) == -1) { - qWarning("QProcessPrivate::createPipe: Cannot create pipe %p: %s", - pipe, qPrintable(qt_error_string(errno))); - } -#else if (::pipe(pipe) != 0) { qWarning("QProcessPrivate::createPipe: Cannot create pipe %p: %s", pipe, qPrintable(qt_error_string(errno))); } -#endif ::fcntl(pipe[0], F_SETFD, FD_CLOEXEC); ::fcntl(pipe[1], F_SETFD, FD_CLOEXEC); } -- cgit v0.12 From dacc8cb0b2abd5ec3e9603c9bcf5b8f489639404 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 22 May 2009 18:14:34 +0200 Subject: Reorganise the pipe creation code. Put all pipe creation calls together. Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess_unix.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index b06e217..e87c314 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -580,29 +580,27 @@ void QProcessPrivate::startProcess() processManager()->start(); // Initialize pipes + if (!createChannel(stdinChannel) || + !createChannel(stdoutChannel) || + !createChannel(stderrChannel)) + return; qt_create_pipe(childStartedPipe); + qt_create_pipe(deathPipe); + ::fcntl(deathPipe[0], F_SETFD, FD_CLOEXEC); + ::fcntl(deathPipe[1], F_SETFD, FD_CLOEXEC); + if (threadData->eventDispatcher) { startupSocketNotifier = new QSocketNotifier(childStartedPipe[0], QSocketNotifier::Read, q); QObject::connect(startupSocketNotifier, SIGNAL(activated(int)), q, SLOT(_q_startupNotification())); - } - qt_create_pipe(deathPipe); - ::fcntl(deathPipe[0], F_SETFD, FD_CLOEXEC); - ::fcntl(deathPipe[1], F_SETFD, FD_CLOEXEC); - if (threadData->eventDispatcher) { deathNotifier = new QSocketNotifier(deathPipe[0], QSocketNotifier::Read, q); QObject::connect(deathNotifier, SIGNAL(activated(int)), q, SLOT(_q_processDied())); } - if (!createChannel(stdinChannel) || - !createChannel(stdoutChannel) || - !createChannel(stderrChannel)) - return; - // Start the process (platform dependent) q->setProcessState(QProcess::Starting); -- cgit v0.12 From 88316df0e845ee11b436c8dad9f1a225f52eb08c Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Fri, 22 May 2009 15:06:49 +0200 Subject: wording: Warnung -> Achtung --- translations/qt_de.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/translations/qt_de.ts b/translations/qt_de.ts index 33f9ea8..7752970 100644 --- a/translations/qt_de.ts +++ b/translations/qt_de.ts @@ -66,15 +66,15 @@ Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. Some video features have been disabled. - Warnung: Das Paket gstreamer0.10-plugins-good ist nicht installiert. -Einige Video-Funktionen stehen nicht zur VerfĂ¼gung. + Achtung: Das Paket gstreamer0.10-plugins-good ist nicht installiert. +Einige Video-Funktionen stehen nicht zur VerfĂ¼gung. Warning: You do not seem to have the base GStreamer plugins installed. All audio and video support has been disabled - Warnung: Die grundlegenden GStreamer-plugins sind nicht installiert. -Die Audio- und Video-UnterstĂ¼tzung wurde abgeschaltet + Achtung: Die grundlegenden GStreamer-Plugins sind nicht installiert. +Die Audio- und Video-UnterstĂ¼tzung steht nicht zur VerfĂ¼gung. @@ -1373,7 +1373,7 @@ nach Warning: - Warnung: + Achtung: -- cgit v0.12 From 0fd48121fc5695b6f526839a3e6c7863bcef0074 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Fri, 22 May 2009 15:08:28 +0200 Subject: wording: Voransicht -> Vorschau --- translations/qt_de.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/qt_de.ts b/translations/qt_de.ts index 7752970..4fa3027 100644 --- a/translations/qt_de.ts +++ b/translations/qt_de.ts @@ -291,12 +291,12 @@ Bitte prĂ¼fen Sie die Gstreamer-Installation und stellen Sie sicher, dass das Pa Preview File Info - Voransicht der Datei-Information + Vorschau der Datei-Informationen Preview File Contents - Voransicht des Datei-Inhalts + Vorschau des Datei-Inhalts -- cgit v0.12 From f00f66b2d2e3d892980f3957eebd7bc36ac315b4 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Fri, 22 May 2009 15:10:21 +0200 Subject: wrong translation of the Chinese writing systems The translations for Traditional and Simplified Chinese are Chinesisch (Langzeichen) and Chinesisch (Kurzzeichen) --- translations/qt_de.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/qt_de.ts b/translations/qt_de.ts index 4fa3027..b82e9a3 100644 --- a/translations/qt_de.ts +++ b/translations/qt_de.ts @@ -1887,12 +1887,12 @@ Möchten sie die Datei trotzdem löschen? Simplified Chinese - Vereinfachtes Chinesisch + Chinesisch (Kurzzeichen) Traditional Chinese - Traditionelles Chinesisch + Chinesisch (Langzeichen) -- cgit v0.12 From a4662d096c46003df2e3c9e2b3ece294fd134986 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Fri, 22 May 2009 15:14:18 +0200 Subject: quite a bunch of fixes and suggenstions If it comes to unification in wording style, there is a long road ahead... --- translations/qt_de.ts | 144 +++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/translations/qt_de.ts b/translations/qt_de.ts index b82e9a3..f623925 100644 --- a/translations/qt_de.ts +++ b/translations/qt_de.ts @@ -85,7 +85,7 @@ Die Audio- und Video-UnterstĂ¼tzung steht nicht zur VerfĂ¼gung. Check your Gstreamer installation and make sure you have libgstreamer-plugins-base installed. - Das Abspielen konnte nicht gestartet werden. + Die Wiedergabe kann nicht gestartet werden. Bitte prĂ¼fen Sie die Gstreamer-Installation und stellen Sie sicher, dass das Paket libgstreamer-plugins-base installiert ist. @@ -139,7 +139,7 @@ Bitte prĂ¼fen Sie die Gstreamer-Installation und stellen Sie sicher, dass das Pa Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% - Die Regler wird zur Einstellung der Lautstärke benutzt. Die Position links entspricht 0%; die Position rechts entspricht %1% + Mit diesem Regler stellen Sie die Lautstärke ein. Die Position links entspricht 0%; die Position rechts entspricht %1% @@ -392,7 +392,7 @@ Bitte prĂ¼fen Sie die Gstreamer-Installation und stellen Sie sicher, dass das Pa Sort by &Name - Nach &Name sortieren + Nach &Namen sortieren @@ -497,7 +497,7 @@ Bitte prĂ¼fen Sie die Gstreamer-Installation und stellen Sie sicher, dass das Pa File not found. Check path and filename. %1 -Datei konnte nicht gefunden werden. +Datei kann nicht gefunden werden. ĂœberprĂ¼fen Sie Pfad und Dateinamen. @@ -617,7 +617,7 @@ nach Defaults - Defaults + Voreinstellungen @@ -699,7 +699,7 @@ nach Contains commands to manipulate the window - Enthält Befehle zum Ă„ndern der FenstergrĂ¶ĂŸe + Enthält Befehle zum Ă„ndern der FenstergrĂ¶ĂŸe @@ -772,18 +772,18 @@ nach The protocol `%1' does not support getting files - Das Protokoll `%1' unterstĂ¼tzt nicht das Laden von Files + Das Protokoll `%1' unterstĂ¼tzt nicht das Laden von Dateien The protocol `%1' does not support putting files - Das Protokoll `%1' unterstĂ¼tzt nicht das Speichern von Files + Das Protokoll `%1' unterstĂ¼tzt nicht das Speichern von Dateien The protocol `%1' does not support copying or moving files or directories - Das Protokoll `%1' unterstĂ¼tzt nicht das Kopieren oder Verschieben von Dateien oder Verzeichnissen + Das Protokoll `%1' unterstĂ¼tzt nicht das Kopieren oder Verschieben von Dateien oder Verzeichnissen @@ -847,7 +847,7 @@ nach Operation on socket is not supported - Diese Socketoperation wird nicht unterstĂ¼tzt + Diese Socket-Operation wird nicht unterstĂ¼tzt @@ -899,7 +899,7 @@ nach Incompatible Qt Library Error - Qt Bibliothek ist inkompatibel + Die Qt-Bibliothek ist inkompatibel @@ -909,7 +909,7 @@ nach Activates the program's main window - Aktiviert das Programmhauptfenster + Aktiviert das Hauptfenster der Anwendung @@ -1066,17 +1066,17 @@ nach Unable to commit transaction - Die Transaktion konnte nicht durchgefĂ¼hrt werden (Operation 'commit' fehlgeschlagen) + Die Transaktion kann nicht durchgefĂ¼hrt werden (Operation 'commit' fehlgeschlagen) Unable to rollback transaction - Die Transaktion konnte nicht rĂ¼ckgängig gemacht werden (Operation 'rollback' fehlgeschlagen) + Die Transaktion kann nicht rĂ¼ckgängig gemacht werden (Operation 'rollback' fehlgeschlagen) Unable to set autocommit - 'autocommit' konnte nicht aktiviert werden + 'autocommit' kann nicht aktiviert werden @@ -1085,32 +1085,32 @@ nach Unable to execute statement - Der Befehl konnte nicht ausgefĂ¼hrt werden + Der Befehl kann nicht ausgefĂ¼hrt werden Unable to prepare statement - Der Befehl konnte nicht initialisiert werden + Der Befehl kann nicht initialisiert werden Unable to bind variable - Die Variable konnte nicht gebunden werden + Die Variable kann nicht gebunden werden Unable to fetch record %1 - Der Datensatz %1 konnte nicht abgeholt werden + Der Datensatz %1 kann nicht abgeholt werden Unable to fetch next - Der nächste Datensatz konnte nicht abgeholt werden + Der nächste Datensatz kann nicht abgeholt werden Unable to fetch first - Der erste Datensatz konnte nicht abgeholt werden + Der erste Datensatz kann nicht abgeholt werden @@ -1358,7 +1358,7 @@ nach &Show this message again - Diese Meldung noch einmal an&zeigen + Diese Meldung wieder an&zeigen @@ -1397,12 +1397,12 @@ nach Cannot open %1 for input - %1 konnte nicht zum Lesen geöffnet werden + %1 kann nicht zum Lesen geöffnet werden Cannot open for output - Das Ă–ffnen zum Schreiben schlug fehl + Das Ă–ffnen zum Schreiben ist fehlgeschlagen @@ -1565,12 +1565,12 @@ Stellen Sie sicher, dass der Verzeichnisname richtig ist. '%1' is write protected. Do you want to delete it anyway? '%1' ist schreibgeschĂ¼tzt. -Möchten sie die Datei trotzdem löschen? +Möchten Sie die Datei trotzdem löschen? Are sure you want to delete '%1'? - Sind Sie sicher, dass Sie %1 löschen möchten? + Sind Sie sicher, dass Sie '%1' löschen möchten? @@ -1624,7 +1624,7 @@ Möchten sie die Datei trotzdem löschen? Look in: - Suche in: + Suchen in: @@ -1658,7 +1658,7 @@ Möchten sie die Datei trotzdem löschen? %1 bytes - %1 byte + %1 Byte @@ -2296,7 +2296,7 @@ Möchten sie die Datei trotzdem löschen? SSL handshake failed - Es trat ein Fehler im Ablauf des SSL-Protokolls auf. + Im Ablauf des SSL-Protokolls ist ein Fehler aufgetreten. @@ -2580,7 +2580,7 @@ Möchten sie die Datei trotzdem löschen? The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) - Das Plugin '%1' verwendet eine inkompatible Qt-Bibliothek. (Im Debug- und Release-Modus erstellte Bibliotheken können nicht zusammen verwendet werden.) + Das Plugin '%1' verwendet eine inkompatible Qt-Bibliothek. (Im Debug- bzw. Release-Modus erstellte Bibliotheken können nicht zusammen verwendet werden.) @@ -2670,7 +2670,7 @@ Möchten sie die Datei trotzdem löschen? %1: Connection refused - %1: Der Aufbau einer Verbindung wurde verweigert + %1: Der Verbindungsaufbau wurde verweigert @@ -2696,13 +2696,13 @@ Möchten sie die Datei trotzdem löschen? %1: Socket resource error - %1: Socketfehler (Ressourcenproblem) + %1: Socket-Fehler (Ressourcenproblem) %1: Socket operation timed out - %1: ZeitĂ¼berschreitung bei Socketoperation + %1: ZeitĂ¼berschreitung bei Socket-Operation @@ -2721,7 +2721,7 @@ Möchten sie die Datei trotzdem löschen? %1: The socket operation is not supported - %1: Diese Socketoperation wird nicht unterstĂ¼tzt + %1: Diese Socket-Operation wird nicht unterstĂ¼tzt @@ -2740,7 +2740,7 @@ Möchten sie die Datei trotzdem löschen? Unable to open database ' - Die Datenbankverbindung konnte nicht geöffnet werden ' + Die Datenbankverbindung kann nicht geöffnet werden ' @@ -2750,17 +2750,17 @@ Möchten sie die Datei trotzdem löschen? Unable to begin transaction - Es konnte keine Transaktion gestartet werden + Es kann keine Transaktion gestartet werden Unable to commit transaction - Die Transaktion konnte nicht durchgefĂ¼hrt werden (Operation 'commit' fehlgeschlagen) + Die Transaktion kann nicht durchgefĂ¼hrt werden (Operation 'commit' fehlgeschlagen) Unable to rollback transaction - Die Transaktion konnte nicht rĂ¼ckgängig gemacht werden (Operation 'rollback' fehlgeschlagen) + Die Transaktion kann nicht rĂ¼ckgängig gemacht werden (Operation 'rollback' fehlgeschlagen) @@ -3422,7 +3422,7 @@ Möchten sie die Datei trotzdem löschen? Socket error on %1: %2 - Socketfehler bei %1: %2 + Socket-Fehler bei %1: %2 @@ -3815,7 +3815,7 @@ Möchten sie die Datei trotzdem löschen? Print To File ... - In Datei drucken + In Datei drucken ... @@ -4022,12 +4022,12 @@ Bitte wählen Sie einen anderen Dateinamen. Print to File (PDF) - Druck in PDF-Datei + In PDF-Datei drucken Print to File (Postscript) - Druck in Postscript-Datei + In Postscript-Datei drucken @@ -4967,97 +4967,97 @@ Bitte wählen Sie einen anderen Dateinamen. Open URL - Ă–ffne URL + URL öffnen Launch Mail - Start Mail + Mail starten Launch Media - Start Media Player + Medienspieler starten Launch (0) - Start (0) + (0) starten Launch (1) - Start (1) + (1) starten Launch (2) - Start (2) + (2) starten Launch (3) - Start (3) + (3) starten Launch (4) - Start (4) + (4) starten Launch (5) - Start (5) + (5) starten Launch (6) - Start (6) + (6) starten Launch (7) - Start (7) + (7) starten Launch (8) - Start (8) + (8) starten Launch (9) - Start (9) + (9) starten Launch (A) - Start (A) + (A) starten Launch (B) - Start (B) + (B) starten Launch (C) - Start (C) + (C) starten Launch (D) - Start (D) + (D) starten Launch (E) - Start (E) + (E) starten Launch (F) - Start (F) + (F) starten @@ -5385,12 +5385,12 @@ Bitte wählen Sie einen anderen Dateinamen. Error while reading: %1 - Beim Lesen trat ein Fehler auf: %1 + Beim Lesen ist ein Fehler aufgetreten: %1 Error during SSL handshake: %1 - Es trat ein Fehler im Ablauf des SSL-Protokolls auf: %1 + Im Ablauf des SSL-Protokolls ist ein Fehler aufgetreten: %1 @@ -5455,7 +5455,7 @@ Bitte wählen Sie einen anderen Dateinamen. %1: already exists - %1: existiert bereits + %1: Existiert bereits @@ -5469,7 +5469,7 @@ Bitte wählen Sie einen anderen Dateinamen. Unable to open connection - Die Datenbankverbindung konnte nicht geöffnet werden + Die Datenbankverbindung kann nicht geöffnet werden @@ -5495,7 +5495,7 @@ Bitte wählen Sie einen anderen Dateinamen. Operation on socket is not supported - Diese Socketoperation wird nicht unterstĂ¼tzt + Diese Socket-Operation wird nicht unterstĂ¼tzt @@ -7342,7 +7342,7 @@ Bitte wählen Sie einen anderen Dateinamen. %1 is not an atomic type. Casting is only possible to atomic types. - %1 ist kein atomarer Typ. Es können nur "cast"-Operation zu atomaren Typen durchgefĂ¼hrt werden. + %1 ist kein atomarer Typ. "cast"-Operation können nur zu atomaren Typen durchgefĂ¼hrt werden. @@ -7397,17 +7397,17 @@ Bitte wählen Sie einen anderen Dateinamen. Integer division (%1) by zero (%2) is undefined. - Die Ganzzahldivision (%1) durch Null (%2) ist nicht definiert. + Die Ganzzahldivision (%1) durch Null (%2) ist nicht definiert. Division (%1) by zero (%2) is undefined. - Die Division (%1) durch Null (%2) ist nicht definiert. + Die Division (%1) durch Null (%2) ist nicht definiert. Modulus division (%1) by zero (%2) is undefined. - Die Modulo-Division (%1) durch Null (%2) ist nicht definiert. + Die Modulo-Division (%1) durch Null (%2) ist nicht definiert. @@ -7443,13 +7443,13 @@ Bitte wählen Sie einen anderen Dateinamen. The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) - Der Namensraum einer nutzerdefinierten Funktion darf nicht leer sein (fĂ¼r diesen Zweck gibt es den vordefinierten Präfix %1) + Der Namensraum einer benutzerdefinierten Funktion darf nicht leer sein (fĂ¼r diesen Zweck gibt es den vordefinierten Präfix %1) A default namespace declaration must occur before function, variable, and option declarations. - Die Deklaration des Default-Namensraums muss vor Funktions- Variablen- oder Optionsdeklaration erfolgen. + Die Deklaration des Default-Namensraums muss vor Funktions-, Variablen- oder Optionsdeklaration erfolgen. -- cgit v0.12 From 263834072595e8de71136886d607f80b5b015572 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 22 May 2009 19:09:46 +0200 Subject: Disable the SH_Menu_AllowActiveAndDisabled on plastique style. This restore the KDE3's behaviour. Do not disable it on Windows as we are aware of customer using the QPlastiqueStyle on Windows that might rely on this (for behaviour consistancy with others Windows applications) Reviewed-by: jbache Task-number: 254210 --- src/gui/styles/qplastiquestyle.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 66464ff..587f2b5 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -5460,6 +5460,11 @@ int QPlastiqueStyle::styleHint(StyleHint hint, const QStyleOption *option, const case SH_Menu_SubMenuPopupDelay: ret = 96; // from Plastik break; +#ifndef Q_OS_WIN + case SH_Menu_AllowActiveAndDisabled: + ret = false; + break; +#endif default: ret = QWindowsStyle::styleHint(hint, option, widget, returnData); break; -- cgit v0.12 From 73a9e0fac1e1b417878286791877bcefeedb16a1 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 22 May 2009 19:28:41 +0200 Subject: Fix changed behaviour after QEglProperties::value() patch Patch 27fadaa7eb2d58b47e7f0f508e3402e7a8de3894 (Make QEglProperties::value() return the EGL default if not set) changed behaviour. This patch reverts this change to behaviour but keeps QEglProperties::value() returning the EGL default value. --- src/opengl/qegl.cpp | 20 ++++++++++---------- src/opengl/qgl_egl.cpp | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/opengl/qegl.cpp b/src/opengl/qegl.cpp index aebc3cb..c6c258b 100644 --- a/src/opengl/qegl.cpp +++ b/src/opengl/qegl.cpp @@ -119,7 +119,7 @@ bool QEglContext::chooseConfig if (red == props.value(EGL_RED_SIZE) && green == props.value(EGL_GREEN_SIZE) && blue == props.value(EGL_BLUE_SIZE) && - (props.value(EGL_ALPHA_SIZE) == EGL_DONT_CARE || + (props.value(EGL_ALPHA_SIZE) == 0 || alpha == props.value(EGL_ALPHA_SIZE))) { cfg = configs[index]; delete [] configs; @@ -448,7 +448,7 @@ int QEglProperties::value(int name) const case EGL_NATIVE_VISUAL_ID: case EGL_NONE: qWarning("QEglProperties::value() - Attibute %d does not affect config selection", name); - return 0; + return EGL_DONT_CARE; default: qWarning("QEglProperties::value() - Attibute %d is unknown in EGL <=1.4", name); return EGL_DONT_CARE; @@ -640,13 +640,13 @@ QString QEglProperties::toString() const #endif val = value(EGL_DEPTH_SIZE); - if (val != EGL_DONT_CARE) { + if (val != 0) { addTag(str, QLatin1String(" depth=")); str += QString::number(val); } val = value(EGL_STENCIL_SIZE); - if (val != EGL_DONT_CARE) { + if (val != 0) { addTag(str, QLatin1String(" stencil=")); str += QString::number(val); } @@ -696,7 +696,7 @@ QString QEglProperties::toString() const } val = value(EGL_LEVEL); - if (val != EGL_DONT_CARE) { + if (val != 0) { addTag(str, QLatin1String(" level=")); str += QString::number(val); } @@ -747,13 +747,13 @@ QString QEglProperties::toString() const #endif val = value(EGL_SAMPLES); - if (val != EGL_DONT_CARE) { + if (val != 0) { addTag(str, QLatin1String(" samples=")); str += QString::number(val); } val = value(EGL_SAMPLE_BUFFERS); - if (val != EGL_DONT_CARE) { + if (val != 0) { addTag(str, QLatin1String(" sample-buffers=")); str += QString::number(val); } @@ -802,7 +802,7 @@ QString QEglProperties::toString() const #ifdef EGL_LUMINANCE_SIZE val = value(EGL_LUMINANCE_SIZE); - if (val != EGL_DONT_CARE) { + if (val != 0) { addTag(str, QLatin1String(" luminance=")); str += QString::number(val); } @@ -810,7 +810,7 @@ QString QEglProperties::toString() const #ifdef EGL_ALPHA_MASK_SIZE val = value(EGL_ALPHA_MASK_SIZE); - if (val != EGL_DONT_CARE) { + if (val != 0) { addTag(str, QLatin1String(" alpha-mask=")); str += QString::number(val); } @@ -818,7 +818,7 @@ QString QEglProperties::toString() const #ifdef EGL_CONFORMANT val = value(EGL_CONFORMANT); - if (val != EGL_DONT_CARE) { + if (val != 0) { if (val) addTag(str, QLatin1String(" conformant=true")); else diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 98c5710..287c537 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -57,14 +57,14 @@ void qt_egl_set_format(QEglProperties& props, int deviceType, const QGLFormat& f // Set the pixel format to that contained in the QGLFormat // if the system hasn't already chosen a fixed format to // match the pixmap, widget, etc. - if (props.value(EGL_RED_SIZE) == EGL_DONT_CARE || f.redBufferSize() != -1) + if (props.value(EGL_RED_SIZE) == 0 || f.redBufferSize() != -1) props.setValue(EGL_RED_SIZE, f.redBufferSize() == -1 ? 1 : f.redBufferSize()); - if (props.value(EGL_GREEN_SIZE) == EGL_DONT_CARE || f.greenBufferSize() != -1) + if (props.value(EGL_GREEN_SIZE) == 0 || f.greenBufferSize() != -1) props.setValue(EGL_GREEN_SIZE, f.greenBufferSize() == -1 ? 1 : f.greenBufferSize()); - if (props.value(EGL_BLUE_SIZE) == EGL_DONT_CARE || f.blueBufferSize() != -1) + if (props.value(EGL_BLUE_SIZE) == 0 || f.blueBufferSize() != -1) props.setValue(EGL_BLUE_SIZE, f.blueBufferSize() == -1 ? 1 : f.blueBufferSize()); if (f.alpha()) { - if (props.value(EGL_ALPHA_SIZE) == EGL_DONT_CARE || f.alphaBufferSize() != -1) + if (props.value(EGL_ALPHA_SIZE) == 0 || f.alphaBufferSize() != -1) props.setValue(EGL_ALPHA_SIZE, f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize()); } -- cgit v0.12 From c8e908a3ee259576ffe96e382ab677d7e3df1a4f Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 22 May 2009 16:48:51 +0200 Subject: Try to use the X11 visual ID provided by EGL EGL has an EGL_NATIVE_VISUAL_ID which can by used as the window's visual ID. We now try to use this ID to avoid an XVisual <-> EGLConfig mis-match. Of course this is usually broken in the EGL library, so we fall back to trying to match outselves. --- src/opengl/qgl_x11egl.cpp | 104 +++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 480a2dc..74b9038 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -114,13 +114,6 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); #endif - // Create the EGL surface to draw into. - if (!d->eglContext->createSurface(device())) { - delete d->eglContext; - d->eglContext = 0; - return false; - } - return true; } @@ -250,13 +243,34 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, return; } + + // Create the EGL Context (which will also choose the config for us) if (d->glcx) d->glcx->doneCurrent(); QGLContext* oldcx = d->glcx; d->glcx = context; + bool createFailed = false; + if (!d->glcx->isValid()) { + if (!d->glcx->create(shareContext ? shareContext : oldcx)) + createFailed = true; + } + if (createFailed) { + if (deleteOldContext) + delete oldcx; + return; + } + + if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) { + if (deleteOldContext) + delete oldcx; + return; + } + + + + // Make sure native winIds are avaliable if (parentWidget()) { - // force creation of delay-created widgets parentWidget()->winId(); if (parentWidget()->x11Info().screen() != x11Info().screen()) d_func()->xinfo = parentWidget()->d_func()->xinfo; @@ -267,16 +281,55 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, hide(); XVisualInfo vi; + memset(&vi, 0, sizeof(XVisualInfo)); + + // Check to see if EGL is suggesting an appropriate visual id: + EGLint nativeVisualId; + QEglContext* qeglCtx = d->glcx->d_func()->eglContext; + qeglCtx->configAttrib(EGL_NATIVE_VISUAL_ID, &nativeVisualId); + vi.visualid = nativeVisualId; + + if (vi.visualid) { + // EGL has suggested a visual id, so get the rest of the visual info for that id: + XVisualInfo *chosenVisualInfo; + int matchingCount = 0; + chosenVisualInfo = XGetVisualInfo(x11Info().display(), VisualIDMask, &vi, &matchingCount); + if (chosenVisualInfo) { + memcpy(&vi, chosenVisualInfo, sizeof(XVisualInfo)); + XFree(chosenVisualInfo); + } + else { + qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this seems to be invalid!", + nativeVisualId, (int)qeglCtx->config()); + vi.visualid = 0; + } + } + + if (vi.visualid == 0) { + // EGL does not know the visual ID, so try to select an appropriate one ourselves: + EGLint depth; + qeglCtx->configAttrib(EGL_BUFFER_SIZE, &depth); + + int err; + err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), depth, TrueColor, &vi); + if (err == 0) { + qWarning("Warning: Can't find an X visual which matches the EGL config(%d)'s depth (%d)!", + (int)qeglCtx->config(), depth); + depth = x11Info().depth(); + err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), depth, TrueColor, &vi); + if (err == 0) { + qWarning("Error: Couldn't get any matching X visual!"); + return; + } + else + qWarning(" - Falling back to X11 suggested depth (%d)", depth); + } - int err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), x11Info().depth(), TrueColor, &vi); - if (err == 0) { - qWarning("Error: Couldn't get a matching X visual for format"); - return; } XSetWindowAttributes a; - Window p = RootWindow(X11->display, vi.screen); + Window p = RootWindow(x11Info().display(), x11Info().screen()); if (parentWidget()) p = parentWidget()->winId(); @@ -294,27 +347,18 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, create(w); // Create with the ID of the window we've just created - d->eglSurfaceWindowId = w; // Remember the window id we created the surface for - - if (visible) - show(); - bool createFailed = false; - if (!d->glcx->isValid()) { - if (!d->glcx->create(shareContext ? shareContext : oldcx)) - createFailed = true; - } - if (createFailed) { - if (deleteOldContext) - delete oldcx; + // Create the EGL surface to draw into. + if (!d->glcx->d_func()->eglContext->createSurface(this)) { + delete d->glcx->d_func()->eglContext; + d->glcx->d_func()->eglContext = 0; return; } - if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) { - if (deleteOldContext) - delete oldcx; - return; - } + d->eglSurfaceWindowId = w; // Remember the window id we created the surface for + + if (visible) + show(); d->glcx->setWindowCreated(true); } -- cgit v0.12 From 43eccd4e52402b9020a0cf26aa1486784f8abe0e Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 22 May 2009 18:34:05 +0200 Subject: If EGL fails to provide a valid Visual ID, try XRender for ARGBs This patch is inspired by the "Fix ARGB visuals" patch in the Maemo branch. Thanks go to the author of that patch (who isn't signed up to Gitorious and thus can't be named - you know who you are! Thanks!!). This patch should also fix ARGB visuals (even if they are supplied by EGL) as such visuals require a colormap. --- src/opengl/qgl_x11egl.cpp | 64 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 74b9038..514e763 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -295,7 +295,8 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, int matchingCount = 0; chosenVisualInfo = XGetVisualInfo(x11Info().display(), VisualIDMask, &vi, &matchingCount); if (chosenVisualInfo) { - memcpy(&vi, chosenVisualInfo, sizeof(XVisualInfo)); + qDebug("Using X Visual ID (%d) provided by EGL", (int)vi.visualid); + vi = *chosenVisualInfo; XFree(chosenVisualInfo); } else { @@ -305,11 +306,38 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, } } + // If EGL does not know the visual ID, so try to select an appropriate one ourselves, first + // using XRender if we're supposed to have an alpha, then falling back to XGetVisualInfo + + bool useArgb = context->format().alpha() && !context->deviceIsPixmap(); +#if !defined(QT_NO_XRENDER) + if (vi.visualid == 0 && useArgb) { + // Try to use XRender to find an ARGB visual we can use + vi.screen = x11Info().screen(); + vi.depth = 32; + vi.c_class = TrueColor; + XVisualInfo *matchingVisuals; + int matchingCount = 0; + matchingVisuals = XGetVisualInfo(x11Info().display(), + VisualScreenMask|VisualDepthMask|VisualClassMask, + &vi, &matchingCount); + + for (int i = 0; i < matchingCount; ++i) { + XRenderPictFormat *format; + format = XRenderFindVisualFormat(x11Info().display(), matchingVisuals[i].visual); + if (format->type == PictTypeDirect && format->direct.alphaMask) { + vi = matchingVisuals[i]; + qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid); + break; + } + } + XFree(matchingVisuals); + } +#endif + if (vi.visualid == 0) { - // EGL does not know the visual ID, so try to select an appropriate one ourselves: EGLint depth; qeglCtx->configAttrib(EGL_BUFFER_SIZE, &depth); - int err; err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), depth, TrueColor, &vi); if (err == 0) { @@ -320,13 +348,27 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, if (err == 0) { qWarning("Error: Couldn't get any matching X visual!"); return; - } - else + } else qWarning(" - Falling back to X11 suggested depth (%d)", depth); - } + } else + qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth); + // Don't try to use ARGB now unless the visual is 32-bit - even then it might stil fail :-( + if (useArgb) + useArgb = vi.depth == 32; } +// qDebug("Visual Info:"); +// qDebug(" bits_per_rgb=%d", vi.bits_per_rgb); +// qDebug(" red_mask=0x%x", vi.red_mask); +// qDebug(" green_mask=0x%x", vi.green_mask); +// qDebug(" blue_mask=0x%x", vi.blue_mask); +// qDebug(" colormap_size=%d", vi.colormap_size); +// qDebug(" c_class=%d", vi.c_class); +// qDebug(" depth=%d", vi.depth); +// qDebug(" screen=%d", vi.screen); +// qDebug(" visualid=%d", vi.visualid); + XSetWindowAttributes a; Window p = RootWindow(x11Info().display(), x11Info().screen()); @@ -337,9 +379,13 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, a.background_pixel = colmap.pixel(palette().color(backgroundRole())); a.border_pixel = colmap.pixel(Qt::black); - Window w = XCreateWindow(X11->display, p, x(), y(), width(), height(), - 0, vi.depth, InputOutput, vi.visual, - CWBackPixel|CWBorderPixel, &a); + unsigned int valueMask = CWBackPixel|CWBorderPixel; + if(useArgb) { + a.colormap = XCreateColormap(x11Info().display(), p, vi.visual, AllocNone); + valueMask |= CWColormap; + } + Window w = XCreateWindow(x11Info().display(), p, x(), y(), width(), height(), + 0, vi.depth, InputOutput, vi.visual, valueMask, &a); if (deleteOldContext) delete oldcx; -- cgit v0.12 From a5104ef77f71b068228ffe6d7c64845889c18c81 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 23 May 2009 13:18:23 +0200 Subject: Fix another compilation breakage introduced by the fix to the compilation breakage introduced in 6c1d7e57. The fix in fc7a43cce did fix the failure, but created another one because qhostinfo_win.cpp also had a copy of qt_sockaddr_in6 Reviewed-by: Jason McDonald --- src/network/kernel/qhostinfo_win.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp index 0a34e2b..472bc4b 100644 --- a/src/network/kernel/qhostinfo_win.cpp +++ b/src/network/kernel/qhostinfo_win.cpp @@ -72,21 +72,6 @@ struct qt_addrinfo qt_addrinfo *ai_next; }; -// sockaddr_in6 size changed between old and new SDK -// Only the new version is the correct one, so always -// use this structure. -struct qt_in6_addr { - uchar qt_s6_addr[16]; -}; - -struct qt_sockaddr_in6 { - short sin6_family; /* AF_INET6 */ - u_short sin6_port; /* Transport level port number */ - u_long sin6_flowinfo; /* IPv6 flow information */ - struct qt_in6_addr sin6_addr; /* IPv6 address */ - u_long sin6_scope_id; /* set of interfaces for a scope */ -}; - //### #define QT_SOCKLEN_T int #ifndef NI_MAXHOST // already defined to 1025 in ws2tcpip.h? -- cgit v0.12 From 26302d22f4dbf3482aacad89ad65bf5b7ed6ae53 Mon Sep 17 00:00:00 2001 From: axasia Date: Sat, 23 May 2009 23:33:49 +0900 Subject: Update japanese translation of Qt Assistant 4.5 --- translations/assistant_ja.ts | 395 ++++++++++++++++++++++--------------------- 1 file changed, 203 insertions(+), 192 deletions(-) diff --git a/translations/assistant_ja.ts b/translations/assistant_ja.ts index 1853155..5e4d2c9 100644 --- a/translations/assistant_ja.ts +++ b/translations/assistant_ja.ts @@ -1,12 +1,12 @@ - + AboutDialog &Close - + é–‰ă˜ă‚‹(&C) @@ -14,18 +14,19 @@ Warning - + è­¦å‘ Unable to launch external application. - + å¤–éƒ¨ă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ă‚’èµ·å‹•ă§ăă¾ă›ă‚“。 + OK - + OK @@ -37,42 +38,42 @@ Bookmarks - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ Add Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă®è¿½å  Bookmark: - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯: Add in Folder: - + 追å å…ˆăƒ•ă‚©ăƒ«ăƒ€: + - + + New Folder - + æ–°ă—ă„ăƒ•ă‚©ăƒ«ăƒ€ Delete Folder - + ăƒ•ă‚©ăƒ«ăƒ€ă‚’å‰é™¤ Rename Folder - + ăƒ•ă‚©ăƒ«ăƒ€ă®åå‰å¤‰æ›´ @@ -80,23 +81,23 @@ Bookmarks - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ Remove - + å‰é™¤ You are going to delete a Folder, this will also<br>remove it's content. Are you sure to continue? - + ăƒ•ă‚©ăƒ«ăƒ€ă‚’å‰é™¤ă™ă‚‹ă¨ä¸­èº«ă‚‚å‰é™¤ă•ă‚Œă¾ă™ăŒă€ç¶ă‘ă¦ă‚ˆă‚ă—ă„ă§ă™ă‹? New Folder - + æ–°ă—ă„ăƒ•ă‚©ăƒ«ăƒ€ @@ -104,47 +105,47 @@ Filter: - + ăƒ•ă‚£ăƒ«ă‚¿: Remove - + å‰é™¤ Delete Folder - + ăƒ•ă‚©ăƒ«ăƒ€ă‚’å‰é™¤ Rename Folder - + ăƒ•ă‚©ăƒ«ăƒ€ă®åå‰å¤‰æ›´ Show Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă‚’é–‹ă Show Bookmark in New Tab - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă Delete Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă‚’å‰é™¤ Rename Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă®åå‰å¤‰æ›´ Add - + è¿½å  @@ -152,48 +153,48 @@ Add new page - + æ–°ă—ă„ăƒăƒ¼ă‚¸ă®è¿½å  Close current page - + ç¾åœ¨ă®ăƒăƒ¼ă‚¸ă‚’é–‰ă˜ă‚‹ Print Document - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă‚’å°åˆ· unknown - + ä¸æ˜ Add New Page - + æ–°ă—ă„ăƒăƒ¼ă‚¸ă®è¿½å  Close This Page - + ă“ă®ăƒăƒ¼ă‚¸ă‚’é–‰ă˜ă‚‹ Close Other Pages - + ä»–ă®ăƒăƒ¼ă‚¸ă‚’é–‰ă˜ă‚‹ Add Bookmark for this Page... - + ă“ă®ăƒăƒ¼ă‚¸ă‚’ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă«è¿½å ... Search - + 検索 @@ -201,12 +202,12 @@ Open Link - + ăƒªăƒ³ă‚¯ă‚’é–‹ă Open Link in New Tab - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă @@ -214,12 +215,12 @@ Add Filter Name - + ăƒ•ă‚£ăƒ«ă‚¿åă‚’è¿½å  Filter Name: - + ăƒ•ă‚£ăƒ«ă‚¿å: @@ -227,27 +228,27 @@ Previous - + æˆ»ă‚‹ Next - + é€²ă‚€ Case Sensitive - + 大文字/å°æ–‡å­—ă‚’åŒºåˆ¥ă™ă‚‹ Whole words - + å˜èªå˜ä½ă§æ¤œç´¢ă™ă‚‹ <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped - + <img src=":/trolltech/assistant/images/wrap.png">&nbsp;見ă¤ă‹ă‚‰ăªă‘ă‚Œă°å…ˆé ­ă‹ă‚‰æ¤œç´¢ă™ă‚‹ @@ -255,27 +256,27 @@ Font - + ăƒ•ă‚©ăƒ³ăƒˆ &Writing system - + æ–‡å­—ă‚»ăƒƒăƒˆ(&W) &Family - + ăƒ•ă‚©ăƒ³ăƒˆå(&F) &Style - + ă‚¹ă‚¿ă‚¤ăƒ«(&S) &Point size - + ă‚µă‚¤ă‚º(&P) @@ -283,38 +284,39 @@ Help - + ăƒ˜ăƒ«ăƒ— OK - + OK <title>Error 404...</title><div align="center"><br><br><h1>The page could not be found</h1><br><h3>'%1'</h3></div> - + <title>Error 404...</title><div align="center"><br><br><h1>ăƒăƒ¼ă‚¸ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“ă§ă—ăŸ</h1><br><h3>'%1'</h3></div> Copy &Link Location - + ăƒªăƒ³ă‚¯ă®URLă‚’ă‚³ăƒ”ăƒ¼(&L) Open Link in New Tab Ctrl+LMB - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă Ctrl+LMB Open Link in New Tab - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă Unable to launch external application. - + å¤–éƒ¨ă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ă‚’èµ·å‹•ă§ăă¾ă›ă‚“。 + @@ -322,17 +324,17 @@ &Look for: - + 検索文字列(&L): Open Link - + ăƒªăƒ³ă‚¯ă‚’é–‹ă Open Link in New Tab - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă @@ -341,97 +343,98 @@ Install Documentation - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ« Downloading documentation info... - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆæƒ…å ±ă‚’ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰ä¸­... Download canceled. - + ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰ă‚’ä¸­æ­¢ă—ă¾ă—ăŸă€‚ Done. - + 完了. The file %1 already exists. Do you want to overwrite it? - + %1 ă¯æ—¢ă«å­˜åœ¨ă—ă¾ă™ă€‚ä¸æ›¸ăă—ă¾ă™ă‹? Unable to save the file %1: %2. - + ăƒ•ă‚¡ă‚¤ăƒ«ă‚’ä¿å­˜ă§ăă¾ă›ă‚“。%1: %2. Downloading %1... - + %1 ă‚’ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰ä¸­... Download failed: %1. - + ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰å¤±æ•—: %1. Documentation info file is corrupt! - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆæƒ…å ±ăƒ•ă‚¡ă‚¤ăƒ«ăŒä¸æ­£ă§ă™! Download failed: Downloaded file is corrupted. - + ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰å¤±æ•—: ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰ă—ăŸăƒ•ă‚¡ă‚¤ăƒ«ăŒä¸æ­£ă§ă™ă€‚ Installing documentation %1... - + %1 ă®ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă‚’ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ«ä¸­... Error while installing documentation: %1 - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ«ä¸­ă«ă‚¨ăƒ©ăƒ¼ăŒç™ºç”Ÿă—ă¾ă—ăŸ: +%1 Available Documentation: - + 使用å¯èƒ½ăªăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆ: Install - + ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ« Cancel - + ă‚­ăƒ£ăƒ³ă‚»ăƒ« Close - + é–‰ă˜ă‚‹ Installation Path: - + ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ«å…ˆă®ăƒ‘ă‚¹: ... - + ... @@ -440,298 +443,298 @@ Index - + ă‚¤ăƒ³ăƒ‡ăƒƒă‚¯ă‚¹ Contents - + ă‚³ăƒ³ăƒ†ăƒ³ăƒ„ Bookmarks - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ Search - + 検索 Qt Assistant - + Qt Assistant Unfiltered - + ăƒ•ă‚£ăƒ«ă‚¿ăªă— Page Set&up... - + ăƒăƒ¼ă‚¸è¨­å®(&U)... Print Preview... - + å°åˆ·ăƒ—ăƒ¬ăƒ“ăƒ¥ăƒ¼... &Print... - + å°åˆ·(&P)... New &Tab - + æ–°ă—ă„ă‚¿ăƒ–(&T) &Close Tab - + ă‚¿ăƒ–ă‚’é–‰ă˜ă‚‹(&C) &Quit - + 終了(&Q) CTRL+Q - + CTRL+Q &Copy selected Text - + é¸æ中ă®æ–‡å­—ă‚’ă‚³ăƒ”ăƒ¼(&C) &Find in Text... - + 検索(&F)... Find &Next - + æ¬¡ă‚’æ¤œç´¢(&N) Find &Previous - + å‰ă‚’検索(&P) Preferences... - + 設å®... Zoom &in - + 拡大(&I) Zoom &out - + 縮å°(&O) Normal &Size - + æ™®é€ă®å¤§ăă•(&S) Ctrl+0 - + Ctrl+0 ALT+C - + ALT+C ALT+I - + ALT+I ALT+S - + ALT+S &Home - + ăƒ›ăƒ¼ăƒ (&H) Ctrl+Home - + Ctrl+Home &Back - + æˆ»ă‚‹(&B) &Forward - + é€²ă‚€(&F) Sync with Table of Contents - + 内容ă¨ç›®æ¬¡ă‚’åŒæœŸă™ă‚‹ Next Page - + 次ă®ăƒăƒ¼ă‚¸ Ctrl+Alt+Right - + Ctrl+Alt+Right Previous Page - + å‰ă®ăƒăƒ¼ă‚¸ Ctrl+Alt+Left - + Ctrl+Alt+Left Add Bookmark... - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă®è¿½å ... About... - + Qt Assistant ă«ă¤ă„ă¦... Navigation Toolbar - + ăƒăƒ“ă‚²ăƒ¼ă‚·ăƒ§ăƒ³ ăƒ„ăƒ¼ăƒ«ăƒăƒ¼ Toolbars - + ăƒ„ăƒ¼ăƒ«ăƒăƒ¼ Filter Toolbar - + ăƒ•ă‚£ăƒ«ă‚¿ăƒ¼ ăƒ„ăƒ¼ăƒ«ăƒăƒ¼ Filtered by: - + ăƒ•ă‚£ăƒ«ă‚¿æ¡ä»¶: Address Toolbar - + ă‚¢ăƒ‰ăƒ¬ă‚¹ ăƒ„ăƒ¼ăƒ«ăƒăƒ¼ Address: - + ă‚¢ăƒ‰ăƒ¬ă‚¹: Could not find the associated content item. - + 関連付ă„ăŸå†…容ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“。 About %1 - + %1 ă«ă¤ă„㦠Updating search index - + æ¤œç´¢ă‚¤ăƒ³ăƒ‡ăƒƒă‚¯ă‚¹ă‚’æ›´æ–°ä¸­ Looking for Qt Documentation... - + Qt ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă‚’æ¢ă—ă¦ă„ă¾ă™... &Window - + ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦(&W) Minimize - + 最å°åŒ– Ctrl+M - + Ctrl+M Zoom - + ă‚ºăƒ¼ăƒ  &File - + ăƒ•ă‚¡ă‚¤ăƒ«(&F) &Edit - + 編集(&E) &View - + 表示(&V) &Go - + ă‚¸ăƒ£ăƒ³ăƒ—(&G) &Bookmarks - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯(&B) &Help - + ăƒ˜ăƒ«ăƒ—(&H) ALT+O - + ALT+O CTRL+D - + CTRL+D @@ -741,47 +744,47 @@ Add Documentation - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®è¿½å  Qt Compressed Help Files (*.qch) - + åœ§ç¸®æ¸ˆă¿ Qt ăƒ˜ăƒ«ăƒ—ăƒ•ă‚¡ă‚¤ăƒ« (*.qch) The specified file is not a valid Qt Help File! - + 指å®ă•ă‚ŒăŸăƒ•ă‚¡ă‚¤ăƒ«ă¯æœ‰å¹ăª Qt ăƒ˜ăƒ«ăƒ— ăƒ•ă‚¡ă‚¤ăƒ«ă§ă¯ă‚ă‚ă¾ă›ă‚“! The namespace %1 is already registered! - + ăƒăƒ¼ăƒ ă‚¹ăƒăƒ¼ă‚¹ %1 ă¯æ—¢ă«ç™»éŒ²æ¸ˆă¿ă§ă™! Remove Documentation - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®é™¤å» Some documents currently opened in Assistant reference the documentation you are attempting to remove. Removing the documentation will close those documents. - + 除å»ă—ă‚ˆă†ă¨ă—ă¦ă„ă‚‹ă„ăă¤ă‹ă®ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă¯ Assistant ä¸ă§å‚ç…§ă•ă‚Œă¦ă„ă¾ă™ă€‚除å»ă™ă‚‹ă¨ă€ă“ă‚Œă‚‰ă®ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă¯é–‰ă˜ă‚‰ă‚Œă¾ă™ă€‚ Cancel - + ă‚­ăƒ£ăƒ³ă‚»ăƒ« OK - + OK Use custom settings - + 独自設å®ă‚’使用ă™ă‚‹ @@ -789,92 +792,92 @@ Preferences - + è¨­å® Fonts - + ăƒ•ă‚©ăƒ³ăƒˆ Font settings: - + ăƒ•ă‚©ăƒ³ăƒˆè¨­å®: Browser - + ăƒ–ăƒ©ă‚¦ă‚¶ăƒ¼ Application - + ă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ Filters - + ăƒ•ă‚£ăƒ«ă‚¿ Filter: - + ăƒ•ă‚£ăƒ«ă‚¿: Attributes: - + å±æ€§: 1 - + 1 Add - + è¿½å  Remove - + å‰é™¤ Documentation - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆ Registered Documentation: - + 登録済ă¿ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆ: Add... - + 追å ... Options - + ă‚ªăƒ—ă‚·ăƒ§ăƒ³ Current Page - + ç¾åœ¨ă®ăƒăƒ¼ă‚¸ Restore to default - + ăƒ‡ăƒ•ă‚©ăƒ«ăƒˆè¨­å®ă«æˆ»ă™ Homepage - + ăƒ›ăƒ¼ăƒ ăƒăƒ¼ă‚¸ @@ -882,64 +885,64 @@ The specified collection file does not exist! - + 指å®ă•ă‚ŒăŸă‚³ăƒ¬ă‚¯ă‚·ăƒ§ăƒ³ăƒ•ă‚¡ă‚¤ăƒ«ă¯å­˜åœ¨ă—ă¾ă›ă‚“! Missing collection file! - + ă‚³ăƒ¬ă‚¯ă‚·ăƒ§ăƒ³ăƒ•ă‚¡ă‚¤ăƒ«ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“! Invalid URL! - + ä¸æ­£ăªURLă§ă™! Missing URL! - + URLăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“! Unknown widget: %1 - + ä¸æ˜ăªă‚¦ă‚£ă‚¸ă‚§ăƒƒăƒˆ: %1 Missing widget! - + ă‚¦ă‚£ă‚¸ă‚§ăƒƒăƒˆăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“! The specified Qt help file does not exist! - + 指å®ă•ă‚ŒăŸ Qt ăƒ˜ăƒ«ăƒ— ăƒ•ă‚¡ă‚¤ăƒ«ăŒå­˜åœ¨ă—ă¾ă›ă‚“! Missing help file! - + ăƒ˜ăƒ«ăƒ—ăƒ•ă‚¡ă‚¤ăƒ«ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“! Missing filter argument! - + ăƒ•ă‚£ăƒ«ă‚¿å¼•æ•°ăŒä¸è¶³ă—ă¦ă„ă¾ă™! Unknown option: %1 - + ä¸æ˜ăªă‚ªăƒ—ă‚·ăƒ§ăƒ³: %1 Qt Assistant - + Qt Assistant @@ -948,12 +951,16 @@ Reason: %2 - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆăƒ•ă‚¡ă‚¤ăƒ«ă‚’ç™»éŒ²ă§ăă¾ă›ă‚“ă§ă—ăŸă€‚ +%1 + +åŸå› : +%2 Documentation successfully registered. - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®ç™»éŒ²ă«æˆåŸă—ă¾ă—ăŸă€‚ @@ -962,28 +969,32 @@ Reason: Reason: %2 - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆăƒ•ă‚¡ă‚¤ăƒ«ă‚’è§£é™¤ă§ăă¾ă›ă‚“ă§ă—ăŸă€‚ +%1 + +åŸå› : +%2 Documentation successfully unregistered. - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®è§£æ”¾ă«æˆåŸă—ă¾ă—ăŸă€‚ Cannot load sqlite database driver! - + SQLite ăƒ‡ăƒ¼ă‚¿ăƒ™ăƒ¼ă‚¹ ăƒ‰ăƒ©ă‚¤ăƒăƒ¼ă‚’ăƒ­ăƒ¼ăƒ‰ă§ăă¾ă›ă‚“! The specified collection file could not be read! - + 指å®ă•ă‚ŒăŸă‚³ăƒ¬ă‚¯ă‚·ăƒ§ăƒ³ăƒ•ă‚¡ă‚¤ăƒ«ă¯èª­ă¿è¾¼ă‚ă¾ă›ă‚“! Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ @@ -991,12 +1002,12 @@ Reason: Debugging Remote Control - + ăƒªăƒ¢ăƒ¼ăƒˆ ă‚³ăƒ³ăƒˆăƒ­ăƒ¼ăƒ«ă‚’ăƒ‡ăƒăƒƒă‚°ä¸­ Received Command: %1 %2 - + å—ä¿¡ă—ăŸă‚³ăƒăƒ³ăƒ‰: %1 %2 @@ -1004,28 +1015,28 @@ Reason: &Copy - + ă‚³ăƒ”ăƒ¼(&C) Copy &Link Location - + ăƒªăƒ³ă‚¯ă®URLă‚’ă‚³ăƒ”ăƒ¼(&L) Open Link in New Tab - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă Select All - + ă™ă¹ă¦ă‚’é¸æ Open Link - + ăƒªăƒ³ă‚¯ă‚’é–‹ă @@ -1033,27 +1044,27 @@ Reason: Choose a topic for <b>%1</b>: - + <b>%1</b> ă®æ¤œç´¢å…ˆăƒˆăƒ”ăƒƒă‚¯ă‚’é¸æă—ă¦ăă ă•ă„: Choose Topic - + ăƒˆăƒ”ăƒƒă‚¯ă‚’é¸æ &Topics - + ăƒˆăƒ”ăƒƒă‚¯(&T) &Display - + 表示(&D) &Close - + é–‰ă˜ă‚‹(&C) -- cgit v0.12 From 91be6a182c2c16f9abedbaa9e90e776a7a07e34c Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Sun, 24 May 2009 07:42:45 +0400 Subject: Update Russian translation for Qt libraries (xmlpatterns and statemachine are not translated yet) --- translations/qt_ru.qm | Bin 60815 -> 107081 bytes translations/qt_ru.ts | 3042 ++++++++++++++++++++++++------------------------- 2 files changed, 1519 insertions(+), 1523 deletions(-) diff --git a/translations/qt_ru.qm b/translations/qt_ru.qm index 63b7b8b..6467629 100644 Binary files a/translations/qt_ru.qm and b/translations/qt_ru.qm differ diff --git a/translations/qt_ru.ts b/translations/qt_ru.ts index 28e786b..a27b8c4 100644 --- a/translations/qt_ru.ts +++ b/translations/qt_ru.ts @@ -1,37 +1,30 @@ - + AudioOutput <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> - + <html>Đ—Đ²ÑƒĐºĐ¾Đ²Đ¾Đµ уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ <b>%1</b> Đ½Đµ Ñ€Đ°Đ±Đ¾Ñ‚Đ°ĐµÑ‚.<br/>Đ‘ÑƒĐ´ĐµÑ‚ иÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ÑŒÑÑ <b>%2</b>.</html> <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> - + <html>ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡ĐµĐ½Đ¸Đµ Đ½Đ° Đ·Đ²ÑƒĐºĐ¾Đ²Đ¾Đµ уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ <b>%1</b><br/>, ĐºĐ¾Ñ‚Đ¾Ñ€Đ¾Đµ Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ¾ и Đ¸Đ¼ĐµĐµÑ‚ Đ²Ñ‹ÑÑˆĐ¸Đ¹ Đ¿Ñ€Đ¸Đ¾Ñ€Đ¸Ñ‚ĐµÑ‚.</html> Revert back to device '%1' - + Đ’Đ¾Đ·Đ²Ñ€Đ°Ñ‰ĐµĐ½Đ¸Đµ Đº уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Ñƒ '%1' CloseButton - + Close Tab - - - - - PPDOptionsModel - - Name - Đ˜Đ¼Ñ + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ Đ²ĐºĐ»Đ°Đ´ĐºÑƒ @@ -39,32 +32,32 @@ Notifications - + Đ£Đ²ĐµĐ´Đ¾Đ¼Đ»ĐµĐ½Đ¸Ñ Music - + ĐœÑƒĐ·Ñ‹ĐºĐ° Video - + Đ’Đ¸Đ´ĐµĐ¾ Communication - + ĐĐ±Ñ‰ĐµĐ½Đ¸Đµ Games - + Đ˜Đ³Ñ€Ñ‹ Accessibility - + Đ¡Ñ€ĐµĐ´ÑÑ‚Đ²Đ° Đ´Đ»Ñ Đ»ÑĐ´ĐµĐ¹ Ñ Đ¾Đ³Ñ€Đ°Đ½Đ¸Ñ‡ĐµĐ½Đ½Ñ‹Đ¼Đ¸ Đ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ÑÑ‚ÑĐ¼Đ¸ @@ -73,13 +66,15 @@ Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. Some video features have been disabled. - + Đ’Đ½Đ¸Đ¼Đ°Đ½Đ¸Đµ: ĐŸĐ¾Ñ…Đ¾Đ¶Đµ, Đ¿Đ°ĐºĐµÑ‚ gstreamer0.10-plugins-good Đ½Đµ уÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½. + ĐĐµĐºĐ¾Ñ‚Đ¾Ñ€Ñ‹Đµ Đ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ÑÑ‚Đ¸ Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Ñ Đ²Đ¸Đ´ĐµĐ¾ Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Ñ‹. Warning: You do not seem to have the base GStreamer plugins installed. All audio and video support has been disabled - + Đ’Đ½Đ¸Đ¼Đ°Đ½Đ¸Đµ: ĐŸĐ¾Ñ…Đ¾Đ¶Đµ, Đ¾ÑĐ½Đ¾Đ²Đ½Đ¾Đ¹ Đ¼Đ¾Đ´ÑƒĐ»ÑŒ GStreamer Đ½Đµ уÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½. + ĐŸĐ¾Đ´Đ´ĐµÑ€Đ¶ĐºĐ° Đ²Đ¸Đ´ĐµĐ¾ и Đ°ÑƒĐ´Đ¸Đ¾ Đ½ĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ° @@ -90,12 +85,15 @@ Check your Gstreamer installation and make sure you have libgstreamer-plugins-base installed. - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ½Đ°Ñ‡Đ°Ñ‚ÑŒ Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Đµ. + +ĐŸÑ€Đ¾Đ²ĐµÑ€ÑŒÑ‚Đµ уÑÑ‚Đ°Đ½Đ¾Đ²ĐºÑƒ Gstreamer и ÑƒĐ±ĐµĐ´Đ¸Ñ‚ĐµÑÑŒ, +Ñ‡Ñ‚Đ¾ Đ¿Đ°ĐºĐµÑ‚ libgstreamer-plugins-base уÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½. A required codec is missing. You need to install the following codec(s) to play this content: %0 - + ĐÑ‚ÑутÑÑ‚Đ²ÑƒĐµÑ‚ Đ½ĐµĐ¾Đ±Ñ…Đ¾Đ´Đ¸Đ¼Ñ‹Đ¹ ĐºĐ¾Đ´ĐµĐº. Đ’Đ°Đ¼ Đ½ÑƒĐ¶Đ½Đ¾ уÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ ÑĐ»ĐµĐ´ÑƒÑÑ‰Đ¸Đµ ĐºĐ¾Đ´ĐµĐºĐ¸ Đ´Đ»Ñ Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Ñ Đ´Đ°Đ½Đ½Đ¾Đ³Đ¾ ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đ³Đ¾: %0 @@ -107,27 +105,27 @@ have libgstreamer-plugins-base installed. Could not open media source. - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ иÑÑ‚Đ¾Ñ‡Đ½Đ¸Đº Đ¼ĐµĐ´Đ¸Đ°-Đ´Đ°Đ½Đ½Ñ‹Ñ…. Invalid source type. - + ĐĐµĐ²ĐµÑ€Đ½Ñ‹Đ¹ Ñ‚Đ¸Đ¿ иÑÑ‚Đ¾Ñ‡Đ½Đ¸ĐºĐ° Đ¼ĐµĐ´Đ¸Đ°-Đ´Đ°Đ½Đ½Ñ‹Ñ…. Could not locate media source. - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ½Đ°Đ¹Ñ‚Đ¸ иÑÑ‚Đ¾Ñ‡Đ½Đ¸Đº Đ¼ĐµĐ´Đ¸Đ°-Đ´Đ°Đ½Đ½Ñ‹Ñ…. Could not open audio device. The device is already in use. - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ·Đ²ÑƒĐºĐ¾Đ²Đ¾Đµ уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾. Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ ÑƒĐ¶Đµ иÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐµÑ‚ÑÑ. Could not decode media source. - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ´ĐµĐºĐ¾Đ´Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ иÑÑ‚Đ¾Ñ‡Đ½Đ¸Đº Đ¼ĐµĐ´Đ¸Đ°-Đ´Đ°Đ½Đ½Ñ‹Ñ…. @@ -136,14 +134,14 @@ have libgstreamer-plugins-base installed. Volume: %1% - + Đ“Ñ€Đ¾Đ¼ĐºĐ¾ÑÑ‚ÑŒ: %1% Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% - + Đ˜ÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐ¹Ñ‚Đµ Đ¿Đ¾Đ»Đ·ÑƒĐ½Đ¾Đº Đ´Đ»Ñ Đ½Đ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ Đ³Ñ€Đ¾Đ¼ĐºĐ¾ÑÑ‚Đ¸. ĐÑ€Đ°Đ¹Đ½ÑÑ Đ»ĐµĐ²Đ°Ñ Đ¿Đ¾Đ·Đ¸Ñ†Đ¸Ñ ÑĐ¾Đ¾Ñ‚Đ²ĐµÑ‚ÑÑ‚Đ²ÑƒĐµÑ‚ 0%, ÑĐ°Đ¼Đ°Ñ Đ¿Ñ€Đ°Đ²Đ°Ñ - %1% @@ -151,7 +149,7 @@ have libgstreamer-plugins-base installed. %1, %2 not defined - + %1, %2 Đ½Đµ Đ¾Đ¿Ñ€ĐµĐ´ĐµĐ»ĐµĐ½ @@ -164,52 +162,52 @@ have libgstreamer-plugins-base installed. True - True + Да False - False + ĐĐµÑ‚ Insert - Đ’ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ + Đ’ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ Update - ĐĐ±Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ + ĐĐ±Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Delete - Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ + Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ Q3FileDialog - + Copy or Move a File - ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ или Đ¿ĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ Ñ„Đ°Đ¹Đ» + ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ или Đ¿ĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ Ñ„Đ°Đ¹Đ» Read: %1 - ĐÑ‚ĐºÑ€Ñ‹Ñ‚Đ¸Đµ: %1 + Đ§Ñ‚ĐµĐ½Đ¸Đµ: %1 Write: %1 - Đ—Đ°Đ¿Đ¸ÑÑŒ: %1 + Đ—Đ°Đ¿Đ¸ÑÑŒ: %1 - + Cancel - ĐÑ‚Đ¼ĐµĐ½Đ° + ĐÑ‚Đ¼ĐµĐ½Đ° @@ -217,307 +215,307 @@ have libgstreamer-plugins-base installed. All Files (*) - Đ’Ñе Ñ„Đ°Đ¹Đ»Ñ‹ (*) + Đ’Ñе Ñ„Đ°Đ¹Đ»Ñ‹ (*) Name - Đ˜Đ¼Ñ + Đ˜Đ¼Ñ Size - Đ Đ°Đ·Đ¼ĐµÑ€ + Đ Đ°Đ·Đ¼ĐµÑ€ Type - Đ¢Đ¸Đ¿ + Đ¢Đ¸Đ¿ Date - Đ”Đ°Ñ‚Đ° + Đ”Đ°Ñ‚Đ° Attributes - ĐÑ‚Ñ€Đ¸Đ±ÑƒÑ‚Ñ‹ + ĐÑ‚Ñ€Đ¸Đ±ÑƒÑ‚Ñ‹ &OK - &OK + &Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ Look &in: - &Đ¡Đ¼Đ¾Ñ‚Ñ€ĐµÑ‚ÑŒ Đ²: + &ĐŸĐ°Đ¿ĐºĐ°: File &name: - &Đ˜Đ¼Ñ Ñ„Đ°Đ¹Đ»Đ°: + &Đ˜Đ¼Ñ Ñ„Đ°Đ¹Đ»Đ°: File &type: - &Đ¢Đ¸Đ¿ Ñ„Đ°Đ¹Đ»Đ°: + &Đ¢Đ¸Đ¿ Ñ„Đ°Đ¹Đ»Đ°: Back - ĐĐ°Đ·Đ°Đ´ + ĐĐ°Đ·Đ°Đ´ One directory up - Đ’Đ²ĐµÑ€Ñ… Đ½Đ° Đ¾Đ´Đ¸Đ½ ÑƒÑ€Đ¾Đ²ĐµĐ½ÑŒ + ĐĐ° Đ¾Đ´Đ¸Đ½ ÑƒÑ€Đ¾Đ²ĐµĐ½ÑŒ Đ²Đ²ĐµÑ€Ñ… Create New Folder - Đ¡Đ¾Đ·Đ´Đ°Ñ‚ÑŒ Đ½Đ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + Đ¡Đ¾Đ·Đ´Đ°Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ List View - Đ¡Đ¿Đ¸ÑĐ¾Đº + Đ¡Đ¿Đ¸ÑĐ¾Đº Detail View - Đ”ĐµÑ‚Đ°Đ»ÑŒĐ½Ñ‹Đ¹ Đ²Đ¸Đ´ + ĐŸĐ¾Đ´Ñ€Đ¾Đ±Đ½Ñ‹Đ¹ Đ²Đ¸Đ´ Preview File Info - ĐŸÑ€ĐµĐ´Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ Đ¸Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Đ¸ Đ¾ Ñ„Đ°Đ¹Đ»Đµ + ĐŸÑ€ĐµĐ´Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ Đ¸Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Đ¸ Đ¾ Ñ„Đ°Đ¹Đ»Đµ Preview File Contents - ĐŸÑ€ĐµĐ´Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đ³Đ¾ Ñ„Đ°Đ¹Đ»Đ° + ĐŸÑ€ĐµĐ´Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đ³Đ¾ Ñ„Đ°Đ¹Đ»Đ° Read-write - Đ§Ñ‚ĐµĐ½Đ¸Đµ-Đ·Đ°Đ¿Đ¸ÑÑŒ + Đ§Ñ‚ĐµĐ½Đ¸Đµ и Đ·Đ°Đ¿Đ¸ÑÑŒ Read-only - Đ¢Đ¾Đ»ÑŒĐºĐ¾ Ñ‡Ñ‚ĐµĐ½Đ¸Đµ + Đ¢Đ¾Đ»ÑŒĐºĐ¾ Ñ‡Ñ‚ĐµĐ½Đ¸Đµ Write-only - Đ¢Đ¾Đ»ÑŒĐºĐ¾ Đ·Đ°Đ¿Đ¸ÑÑŒ + Đ¢Đ¾Đ»ÑŒĐºĐ¾ Đ·Đ°Đ¿Đ¸ÑÑŒ Inaccessible - ĐĐµÑ‚ Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ° + ĐĐµÑ‚ Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ° Symlink to File - Đ¡ÑÑ‹Đ»ĐºĐ° Đ½Đ° Ñ„Đ°Đ¹Đ» + Đ¡ÑÑ‹Đ»ĐºĐ° Đ½Đ° Ñ„Đ°Đ¹Đ» Symlink to Directory - Đ¡ÑÑ‹Đ»ĐºĐ° Đ½Đ° ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + Đ¡ÑÑ‹Đ»ĐºĐ° Đ½Đ° ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ Symlink to Special - Đ¡ÑÑ‹Đ»ĐºĐ° Đ½Đ° ÑĐ¿ĐµÑ†Ñ„Đ°Đ¹Đ» + Đ¡ÑÑ‹Đ»ĐºĐ° Đ½Đ° ÑĐ¿ĐµÑ†Ñ„Đ°Đ¹Đ» File - Đ¤Đ°Đ¹Đ» + Đ¤Đ°Đ¹Đ» Dir - ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³ + ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³ Special - Đ¡Đ¿ĐµÑ†Ñ„Đ°Đ¹Đ» + Đ¡Đ¿ĐµÑ†Ñ„Đ°Đ¹Đ» Open - ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Save As - Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ ĐºĐ°Đº + Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ ĐºĐ°Đº &Open - &ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + &ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ &Save - &Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ + &Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ &Rename - &ĐŸĐµÑ€ĐµĐ¸Đ¼ĐµĐ½Đ¾Đ²Đ°Ñ‚ÑŒ + &ĐŸĐµÑ€ĐµĐ¸Đ¼ĐµĐ½Đ¾Đ²Đ°Ñ‚ÑŒ &Delete - &Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ + &Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ R&eload - Đ&Đ±Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ + Đ&Đ±Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Sort by &Name - ĐŸĐ¾ &Đ¸Đ¼ĐµĐ½Đ¸ + ĐŸĐ¾ &Đ¸Đ¼ĐµĐ½Đ¸ Sort by &Size - ĐŸĐ¾ &Ñ€Đ°Đ·Đ¼ĐµÑ€Ñƒ + ĐŸĐ¾ &Ñ€Đ°Đ·Đ¼ĐµÑ€Ñƒ Sort by &Date - ĐŸĐ¾ &Đ´Đ°Ñ‚Đµ + ĐŸĐ¾ &Đ´Đ°Ñ‚Đµ &Unsorted - &Đе ÑƒĐ¿Đ¾Ñ€ÑĐ´Đ¾Ñ‡Đ¸Đ²Đ°Ñ‚ÑŒ + &Đе ÑƒĐ¿Đ¾Ñ€ÑĐ´Đ¾Ñ‡Đ¸Đ²Đ°Ñ‚ÑŒ Sort - Đ£Đ¿Đ¾Ñ€ÑĐ´Đ¾Ñ‡Đ¸Ñ‚ÑŒ + Đ£Đ¿Đ¾Ñ€ÑĐ´Đ¾Ñ‡Đ¸Ñ‚ÑŒ Show &hidden files - ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ &ÑĐºÑ€Ñ‹Ñ‚Ñ‹Đµ Ñ„Đ°Đ¹Đ»Ñ‹ + ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ ÑĐºÑ€&Ñ‹Ñ‚Ñ‹Đµ Ñ„Đ°Đ¹Đ»Ñ‹ the file - Ñ„Đ°Đ¹Đ» + Ñ„Đ°Đ¹Đ» the directory - ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ the symlink - ÑÑÑ‹Đ»ĐºÑƒ + ÑÑÑ‹Đ»ĐºÑƒ Delete %1 - Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ %1 + Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ %1 <qt>Are you sure you wish to delete %1 "%2"?</qt> - <qt>Đ’Ñ‹ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ %1 "%2"?</qt> + <qt>Đ’Ñ‹ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ %1 "%2"?</qt> &Yes - &Да + &Да &No - &ĐĐµÑ‚ + &ĐĐµÑ‚ New Folder 1 - ĐĐ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ 1 + ĐĐ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ 1 New Folder - ĐĐ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + ĐĐ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ New Folder %1 - ĐĐ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ %1 + ĐĐ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ %1 Find Directory - ĐĐ°Đ¹Ñ‚Đ¸ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + ĐĐ°Đ¹Ñ‚Đ¸ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ Directories - ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¸ + ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¸ Directory: - ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³: + ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³: Error - ĐÑˆĐ¸Đ±ĐºĐ° + ĐÑˆĐ¸Đ±ĐºĐ° %1 File not found. Check path and filename. - %1 + %1 Đ¤Đ°Đ¹Đ» Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½. ĐŸÑ€Đ¾Đ²ĐµÑ€ÑŒÑ‚Đµ Đ¿Ñ€Đ°Đ²Đ¸Đ»ÑŒĐ½Đ¾ÑÑ‚ÑŒ Đ¿ÑƒÑ‚Đ¸ и Đ¸Đ¼ĐµĐ½Đ¸ Ñ„Đ°Đ¹Đ»Đ°. All Files (*.*) - Đ’Ñе Ñ„Đ°Đ¹Đ»Ñ‹ (*.*) + Đ’Ñе Ñ„Đ°Đ¹Đ»Ñ‹ (*.*) Open - ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Select a Directory - Đ’Ñ‹Đ±Ñ€Đ°Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + Đ’Ñ‹Đ±Ñ€Đ°Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ @@ -527,21 +525,21 @@ Check path and filename. Could not read directory %1 - ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ĐµÑ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¿Ñ€Đ¾Ñ‡Đ¸Ñ‚Đ°Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ %1 Could not create directory %1 - ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Đ·Đ´Đ°Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ ÑĐ¾Đ·Đ´Đ°Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ %1 Could not remove file or directory %1 - ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ Ñ„Đ°Đ¹Đ» или ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ Ñ„Đ°Đ¹Đ» или ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ %1 @@ -550,7 +548,7 @@ Check path and filename. %1 to %2 - ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿ĐµÑ€ĐµĐ¸Đ¼ĐµĐ½Đ¾Đ²Đ°Ñ‚ÑŒ + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¿ĐµÑ€ĐµĐ¸Đ¼ĐµĐ½Đ¾Đ²Đ°Ñ‚ÑŒ %1 Đ² %2 @@ -559,14 +557,14 @@ to Could not open %1 - ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ %1 Could not write %1 - ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ·Đ°Đ¿Đ¸ÑĐ°Ñ‚ÑŒ + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ·Đ°Đ¿Đ¸ÑĐ°Ñ‚ÑŒ %1 @@ -575,12 +573,12 @@ to Line up - Đ’Ñ‹Ñ€Đ¾Đ²Đ½ÑÑ‚ÑŒ + Đ’Ñ‹Ñ€Đ¾Đ²Đ½ÑÑ‚ÑŒ Customize... - ĐĐ°ÑÑ‚Ñ€Đ¾Đ¸Ñ‚ÑŒ... + ĐĐ°ÑÑ‚Ñ€Đ¾Đ¸Ñ‚ÑŒ... @@ -588,7 +586,7 @@ to Operation stopped by the user - ĐĐ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Đ¿Ñ€ĐµÑ€Đ²Đ°Đ½Đ° Đ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ĐµĐ»ĐµĐ¼ + ĐĐ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Đ¿Ñ€ĐµÑ€Đ²Đ°Đ½Đ° Đ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ĐµĐ»ĐµĐ¼ @@ -597,36 +595,36 @@ to Cancel - ĐÑ‚Đ¼ĐµĐ½Đ° + ĐÑ‚Đ¼ĐµĐ½Đ° Q3TabDialog - - + + OK - OK + Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ - + Apply - ĐŸÑ€Đ¸Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ + ĐŸÑ€Đ¸Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ Help - Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° + Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° Defaults - ĐŸĐ¾ ÑƒĐ¼Đ¾Đ»Ñ‡Đ°Đ½Đ¸Ñ + ĐŸĐ¾ ÑƒĐ¼Đ¾Đ»Ñ‡Đ°Đ½Đ¸Ñ Cancel - ĐÑ‚Đ¼ĐµĐ½Đ° + ĐÑ‚Đ¼ĐµĐ½Đ° @@ -634,38 +632,38 @@ to &Undo - &ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ + &ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ &Redo - &ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ + &ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ Cu&t - &Đ’Ñ‹Ñ€ĐµĐ·Đ°Ñ‚ÑŒ + &Đ’Ñ‹Ñ€ĐµĐ·Đ°Ñ‚ÑŒ &Copy - &ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ + &ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ &Paste - &Đ’ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ + Đ’&ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ Clear - ĐÑ‡Đ¸ÑÑ‚Đ¸Ñ‚ÑŒ + ĐÑ‡Đ¸ÑÑ‚Đ¸Ñ‚ÑŒ Select All - Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ²Ñе + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ²Ñе @@ -673,67 +671,67 @@ to System - + Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ½Đ¾Đµ Đ¼ĐµĐ½Ñ Restore up - + Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Minimize - Đ¡Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ + ĐœĐ¸Đ½Đ¸Đ¼Đ¸Đ·Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Restore down - + Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Maximize - Đ Đ°Đ·Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ + Đ Đ°ÑĐ¿Đ°Ñ…Đ½ÑƒÑ‚ÑŒ Close - Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ Contains commands to manipulate the window - + Đ¡Đ¾Đ´ĐµÑ€Đ¶Đ¸Ñ‚ ĐºĐ¾Đ¼Đ°Đ½Đ´Ñ‹ ÑƒĐ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Ñ Đ¾ĐºĐ½Đ¾Đ¼ Puts a minimized back to normal - + Đ’Đ¾Đ·Đ²Ñ€Đ°Ñ‰Đ°ĐµÑ‚ Đ¼Đ¸Đ½Đ¸Đ¼Đ¸Đ·Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ½Đ¾Đµ Đ¾ĐºĐ½Đ¾ Đ² Đ½Đ¾Ñ€Đ¼Đ°Đ»ÑŒĐ½Đ¾Đµ ÑĐ¾ÑÑ‚Đ¾ÑĐ½Đ¸Đµ Moves the window out of the way - + Đ¡Đ²Đ¾Ñ€Đ°Ñ‡Đ¸Đ²Đ°ĐµÑ‚ Đ¾ĐºĐ½Đ¾ Puts a maximized window back to normal - + Đ’Đ¾Đ·Đ²Ñ€Đ°Ñ‰Đ°ĐµÑ‚ Ñ€Đ°ÑĐ¿Đ°Ñ…Đ½ÑƒÑ‚Đ¾Đµ Đ¾ĐºĐ½Đ¾ Đ² Đ½Đ¾Ñ€Đ¼Đ°Đ»ÑŒĐ½Đ¾Đµ ÑĐ¾ÑÑ‚Đ¾ÑĐ½Đ¸Đµ Makes the window full screen - + Đ Đ°Đ·Đ²Đ¾Ñ€Đ°Ñ‡Đ¸Đ²Đ°ĐµÑ‚ Đ¾ĐºĐ½Đ¾ Đ½Đ° Đ²ĐµÑÑŒ ÑĐºÑ€Đ°Đ½ Closes the window - + Đ—Ñ‹ĐºÑ€Ñ‹Đ²Đ°ĐµÑ‚ Đ¾ĐºĐ½Đ¾ Displays the name of the window and contains controls to manipulate it - + ĐÑ‚Đ¾Đ±Ñ€Đ°Đ¶Đ°ĐµÑ‚ Đ½Đ°Đ·Đ²Đ°Đ½Đ¸Đµ Đ¾ĐºĐ½Đ° и ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Ñ‚ ĐºĐ¾Đ¼Đ°Đ½Đ´Ñ‹ ÑƒĐ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Ñ Đ¸Đ¼ @@ -741,7 +739,7 @@ to More... - Đ‘Đ¾Đ»ÑŒÑˆĐµ... + Đ‘Đ¾Đ»ÑŒÑˆĐµ... @@ -751,49 +749,49 @@ to The protocol `%1' is not supported - ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ + ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ The protocol `%1' does not support listing directories - ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² + ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² The protocol `%1' does not support creating new directories - ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ ÑĐ¾Đ·Đ´Đ°Đ½Đ¸Đµ Đ½Đ¾Đ²Ñ‹Ñ… ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² + ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ ÑĐ¾Đ·Đ´Đ°Đ½Đ¸Đµ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² The protocol `%1' does not support removing files or directories - ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ ÑƒĐ´Đ°Đ»ĐµĐ½Đ¸Đµ Ñ„Đ°Đ¹Đ»Đ¾Đ² или ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² + ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ ÑƒĐ´Đ°Đ»ĐµĐ½Đ¸Đµ Ñ„Đ°Đ¹Đ»Đ¾Đ² или ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² The protocol `%1' does not support renaming files or directories - ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Đ¿ĐµÑ€ĐµĐ¸Đ¼ĐµĐ½Đ¾Đ²Đ°Đ½Đ¸Đµ Ñ„Đ°Đ¹Đ»Đ¾Đ² или ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² + ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Đ¿ĐµÑ€ĐµĐ¸Đ¼ĐµĐ½Đ¾Đ²Đ°Đ½Đ¸Đµ Ñ„Đ°Đ¹Đ»Đ¾Đ² или ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² The protocol `%1' does not support getting files - ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Đ´Đ¾ÑÑ‚Đ°Đ²ĐºÑƒ Ñ„Đ°Đ¹Đ»Đ¾Đ² + ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Đ´Đ¾ÑÑ‚Đ°Đ²ĐºÑƒ Ñ„Đ°Đ¹Đ»Đ¾Đ² The protocol `%1' does not support putting files - ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Đ¾Ñ‚Đ¿Ñ€Đ°Đ²ĐºÑƒ Ñ„Đ°Đ¹Đ»Đ¾Đ² + ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Đ¾Ñ‚Đ¿Ñ€Đ°Đ²ĐºÑƒ Ñ„Đ°Đ¹Đ»Đ¾Đ² The protocol `%1' does not support copying or moving files or directories - ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ ĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ¸Đµ или Đ¿ĐµÑ€ĐµĐ¼ĐµÑ‰ĐµĐ½Đ¸Đµ Ñ„Đ°Đ¹Đ»Đ¾Đ² и ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² + ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» `%1' Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ ĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ¸Đµ или Đ¿ĐµÑ€ĐµĐ¼ĐµÑ‰ĐµĐ½Đ¸Đµ Ñ„Đ°Đ¹Đ»Đ¾Đ² или ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¾Đ² (unknown) - (Đ½ĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ¾) + (Đ½ĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ¾) @@ -801,27 +799,27 @@ to &Cancel - &ĐÑ‚Đ¼ĐµĐ½Đ° + &ĐÑ‚Đ¼ĐµĐ½Đ° < &Back - < &ĐĐ°Đ·Đ°Đ´ + < &ĐĐ°Đ·Đ°Đ´ &Next > - &Đ’Đ¿ĐµÑ€ĐµĐ´ > + &Đ’Đ¿ĐµÑ€ĐµĐ´ > &Finish - &Đ¤Đ¸Đ½Đ¸Ñˆ + &Đ—Đ°ĐºĐ¾Đ½Ñ‡Đ¸Ñ‚ÑŒ &Help - &Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° + &Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° @@ -832,68 +830,67 @@ to Host not found - + Đ£Đ·ĐµĐ» Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½ Connection refused - ĐÑ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ + ĐÑ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ Connection timed out - + Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ иÑÑ‚ĐµĐºĐ»Đ¾ Operation on socket is not supported - + ĐĐ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Ñ ÑĐ¾ĐºĐµÑ‚Đ¾Đ¼ Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ Socket operation timed out - + Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° Đ¾Đ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Ñ ÑĐ¾ĐºĐµÑ‚Đ¾Đ¼ иÑÑ‚ĐµĐºĐ»Đ¾ Socket is not connected - + Đ¡Đ¾ĐºĐµÑ‚ Đ½Đµ Đ¿Đ¾Đ´ĐºĐ»ÑÑ‡Ñ‘Đ½ Network unreachable - + Đ¡ĐµÑ‚ÑŒ Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° QAbstractSpinBox - + &Step up - + Đ¨Đ°Đ³ Đ²Đ²&ĐµÑ€Ñ… Step &down - + Đ¨Đ°Đ³ Đ²Đ½&из &Select All - + &Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ²Ñе QApplication - - QT_LAYOUT_DIRECTION - Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. - LTR + + Activate + ĐĐºÑ‚Đ¸Đ²Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ @@ -906,37 +903,38 @@ to ĐÑˆĐ¸Đ±ĐºĐ° ÑĐ¾Đ²Đ¼ĐµÑÑ‚Đ¸Đ¼Đ¾ÑÑ‚Đ¸ Đ±Đ¸Đ±Đ»Đ¸Đ¾Ñ‚ĐµĐºĐ¸ Qt - - Activate - + + QT_LAYOUT_DIRECTION + Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. + LTR - + Activates the program's main window - + ĐĐºÑ‚Đ¸Đ²Đ¸Ñ€ÑƒĐµÑ‚ Đ³Đ»Đ°Đ²Đ½Đ¾Đµ Đ¾ĐºĐ½Đ¾ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Ñ‹ QAxSelect - + Select ActiveX Control - + Đ’Ñ‹Đ±ĐµÑ€Đ¸Ñ‚Đµ ĐºĐ¾Đ¼Đ¿Đ¾Đ½ĐµĐ½Ñ‚Ñƒ ActiveX - + OK - OK + Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ - + &Cancel - &ĐÑ‚Đ¼ĐµĐ½Đ° + &ĐÑ‚Đ¼ĐµĐ½Đ° - + COM &Object: - + COM &ĐбÑĐµĐºÑ‚: @@ -944,17 +942,17 @@ to Uncheck - + Đ¡Đ½ÑÑ‚ÑŒ Đ¾Ñ‚Đ¼ĐµÑ‚ĐºÑƒ Check - + ĐÑ‚Đ¼ĐµÑ‚Đ¸Ñ‚ÑŒ Toggle - + ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ @@ -977,17 +975,17 @@ to &Red: - &ĐÑ€Đ°Ñ: + &ĐÑ€Đ°ÑĐ½Ñ‹Đ¹: &Green: - &Зел: + &Đ—ĐµĐ»Ñ‘Đ½Ñ‹Đ¹: Bl&ue: - Đ¡&Đ¸Đ½: + Đ¡&Đ¸Đ½Đ¸Đ¹: @@ -997,7 +995,7 @@ to Select Color - + Đ’Ñ‹Đ±ĐµÑ€Đ¸Ñ‚Đµ Ñ†Đ²ĐµÑ‚ @@ -1007,28 +1005,12 @@ to &Custom colors - &Đ¡Đ¾Đ±ÑÑ‚Đ²ĐµĐ½Đ½Ñ‹Đµ Ñ†Đ²ĐµÑ‚Đ° - - - &Define Custom Colors >> - &Đ’Ñ‹Đ±Ñ€Đ°Ñ‚ÑŒ ÑĐ¾Đ±ÑÑ‚Đ²ĐµĐ½Đ½Ñ‹Đµ Ñ†Đ²ĐµÑ‚Đ° >> - - - OK - OK - - - Cancel - ĐÑ‚Đ¼ĐµĐ½Đ° + &ĐŸÑ€Đ¾Đ¸Đ·Đ²Đ¾Đ»ÑŒĐ½Ñ‹Đµ Ñ†Đ²ĐµÑ‚Đ° &Add to Custom Colors - &Đ”Đ¾Đ±Đ°Đ²Đ¸Ñ‚ÑŒ Đº ÑĐ¾Đ±ÑÑ‚Đ²ĐµĐ½Đ½Ñ‹Đ¼ Ñ†Đ²ĐµÑ‚Đ°Đ¼ - - - Select color - Đ’Ñ‹Đ±Ñ€Đ°Ñ‚ÑŒ Ñ†Đ²ĐµÑ‚ + &Đ”Đ¾Đ±Đ°Đ²Đ¸Ñ‚ÑŒ Đº Đ¿Ñ€Đ¾Đ¸Đ·Đ²Đ¾Đ»ÑŒĐ½Ñ‹Đ¼ Ñ†Đ²ĐµÑ‚Đ°Đ¼ @@ -1037,22 +1019,22 @@ to Open - ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ False - False + ĐĐµÑ‚ True - True + Да Close - Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ @@ -1061,19 +1043,19 @@ to %1: key is empty QSystemSemaphore - + %1: Đ¿ÑƒÑÑ‚Đ¾Đ¹ ĐºĐ»Ñч %1: unable to make key QSystemSemaphore - + %1: Đ½ĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Đ·Đ´Đ°Ñ‚ÑŒ ĐºĐ»Ñч %1: ftok failed QSystemSemaphore - + %1: Đ¾ÑˆĐ¸Đ±ĐºĐ° ftok @@ -1081,22 +1063,22 @@ to Unable to connect - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½Đ¸Ñ‚ÑŒÑÑ Unable to commit transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to rollback transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºĐ°Ñ‚Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to set autocommit - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ уÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Đ°Đ²Ñ‚Đ¾Đ²Ñ‹Đ¿Đ¾Đ»Đ½ĐµĐ½Đ¸Đµ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Đ¸ @@ -1105,32 +1087,32 @@ to Unable to execute statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to prepare statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ´Đ³Đ¾Ñ‚Đ¾Đ²Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to bind variable - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Ñ€Đ¸Đ²ÑĐ·Đ°Ñ‚ÑŒ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ Unable to fetch record %1 - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ %1 Unable to fetch next - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ ÑĐ»ĐµĐ´ÑƒÑÑ‰ÑƒÑ ÑÑ‚Ñ€Đ¾ĐºÑƒ Unable to fetch first - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ Đ¿ĐµÑ€Đ²ÑƒÑ ÑÑ‚Ñ€Đ¾ĐºÑƒ @@ -1184,162 +1166,162 @@ to Done - + Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ QDialogButtonBox - + OK - OK + Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ - - Save - Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ + + &OK + &Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ - + &Save - &Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ + &Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ + + + + Save + Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ Open - ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ - Cancel - ĐÑ‚Đ¼ĐµĐ½Đ° + &Cancel + &ĐÑ‚Đ¼ĐµĐ½Đ° - &Cancel - &ĐÑ‚Đ¼ĐµĐ½Đ° + Cancel + ĐÑ‚Đ¼ĐµĐ½Đ° - Close - Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + &Close + &Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ - &Close - &Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + Close + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ Apply - ĐŸÑ€Đ¸Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ + ĐŸÑ€Đ¸Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ Reset - + Đ¡Đ±Ñ€Đ¾ÑĐ¸Ñ‚ÑŒ Help - Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° + Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° Don't Save - + Đе ÑĐ¾Ñ…Ñ€Đ°Đ½ÑÑ‚ÑŒ Discard - + Đе Đ¿Ñ€Đ¸Đ¼ĐµĐ½ÑÑ‚ÑŒ &Yes - &Да + Đ”&Đ° Yes to &All - + Да Đ´Đ»Ñ &Đ²ÑĐµÑ… &No - &ĐĐµÑ‚ + &ĐĐµÑ‚ N&o to All - + Đ&ĐµÑ‚ Đ´Đ»Ñ Đ²ÑĐµÑ… Save All - + Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ Đ²Ñе Abort - + ĐŸÑ€ĐµÑ€Đ²Đ°Ñ‚ÑŒ Retry - + ĐŸĐ¾Đ¿Ñ€Đ¾Đ±Đ¾Đ²Đ°Ñ‚ÑŒ ĐµÑ‰Ñ‘ Ignore - + Đ˜Đ³Đ½Đ¾Ñ€Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Restore Defaults - + Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Ñ Đ¿Đ¾ ÑƒĐ¼Đ¾Đ»Ñ‡Đ°Đ½Đ¸Ñ Close without Saving - - - - - &OK - &OK + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ без ÑĐ¾Ñ…Ñ€Đ°Đ½ĐµĐ½Đ¸Ñ QDirModel - + Name - Đ˜Đ¼Ñ + Đ˜Đ¼Ñ Size - Đ Đ°Đ·Đ¼ĐµÑ€ + Đ Đ°Đ·Đ¼ĐµÑ€ Kind Match OS X Finder - + Вид Type All other platforms - Đ¢Đ¸Đ¿ + Đ¢Đ¸Đ¿ Date Modified - + Đ”Đ°Ñ‚Đ° Đ¸Đ·Đ¼ĐµĐ½ĐµĐ½Đ¸Ñ @@ -1347,7 +1329,7 @@ to Close - Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ @@ -1365,28 +1347,18 @@ to More - + Đ‘Đ¾Đ»ÑŒÑˆĐµ Less - + ĐœĐµĐ½ÑŒÑˆĐµ QErrorMessage - - &Show this message again - &ĐŸĐ¾ĐºĐ°Đ·Ñ‹Đ²Đ°Ñ‚ÑŒ ÑÑ‚Đ¾ ÑĐ¾Đ¾Đ±Ñ‰ĐµĐ½Đ¸Đµ Đ² Đ´Đ°Đ»ÑŒĐ½ĐµĐ¹ÑˆĐµĐ¼ - - - - &OK - &OK - - - + Debug Message: ĐÑ‚Đ»Đ°Đ´Đ¾Ñ‡Đ½Đ¾Đµ ÑĐ¾Đ¾Đ±Ñ‰ĐµĐ½Đ¸Đµ: @@ -1400,326 +1372,376 @@ to Fatal Error: ĐÑ€Đ¸Ñ‚Đ¸Ñ‡ĐµÑĐºĐ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ°: + + + &Show this message again + &ĐŸĐ¾ĐºĐ°Đ·Ñ‹Đ²Đ°Ñ‚ÑŒ ÑÑ‚Đ¾ ÑĐ¾Đ¾Đ±Ñ‰ĐµĐ½Đ¸Đµ Đ² Đ´Đ°Đ»ÑŒĐ½ĐµĐ¹ÑˆĐµĐ¼ + + + + &OK + &Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ + QFile - + Destination file exists - + Đ¤Đ°Đ¹Đ» ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚ + + + + Will not rename sequential file using block copy + Đе Đ±ÑƒĐ´ĐµÑ‚ Đ¿ĐµÑ€ĐµĐ¸Đ¼ĐµĐ½Đ¾Đ²Ñ‹Đ²Đ°Ñ‚ÑŒ Đ¿Đ¾ÑĐ»ĐµĐ´Đ¾Đ²Đ°Ñ‚ĐµĐ»ÑŒĐ½Ñ‹Đ¹ Ñ„Đ°Đ¹Đ», иÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒÑ ĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ¸Đµ Đ±Đ»Đ¾ĐºĐ° - + Cannot remove source file - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ иÑÑ…Đ¾Đ´Đ½Ñ‹Đ¹ Ñ„Đ°Đ¹Đ» - + Cannot open %1 for input - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ %1 Đ´Đ»Ñ Đ²Đ²Đ¾Đ´Đ° Cannot open for output - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ´Đ»Ñ Đ²Ñ‹Đ²Đ¾Đ´Đ° Failure to write block - + Đ¡Đ±Đ¾Đ¹ Đ·Đ°Đ¿Đ¸Ñи Đ±Đ»Đ¾ĐºĐ° Cannot create %1 for output - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Đ·Đ´Đ°Ñ‚ÑŒ %1 Đ´Đ»Ñ Đ²Ñ‹Đ²Đ¾Đ´Đ° QFileDialog - - + + All Files (*) Đ’Ñе Ñ„Đ°Đ¹Đ»Ñ‹ (*) - - - Back - ĐĐ°Đ·Đ°Đ´ - - - - - List View - Đ¡Đ¿Đ¸ÑĐ¾Đº + + Directories + ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¸ - - - Detail View - Đ”ĐµÑ‚Đ°Đ»ÑŒĐ½Ñ‹Đ¹ Đ²Đ¸Đ´ + + + + + &Open + &ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ - - - File - Đ¤Đ°Đ¹Đ» + + + &Save + &Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ - + Open ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ - - Save As - Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ ĐºĐ°Đº - - - - - - - &Open - &ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + + %1 already exists. +Do you want to replace it? + %1 ÑƒĐ¶Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚. +Đ¥Đ¾Ñ‚Đ¸Ñ‚Đµ Đ·Đ°Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ ĐµĐ³Đ¾? - - - &Save - &Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ + + %1 +File not found. +Please verify the correct file name was given. + %1 +Đ¤Đ°Đ¹Đ» Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½. +ĐŸÑ€Đ¾Đ²ĐµÑ€ÑŒÑ‚Đµ Đ¿Ñ€Đ°Đ²Đ¸Đ»ÑŒĐ½Đ¾ÑÑ‚ÑŒ Đ·Đ°Đ´Đ°Đ½Đ½Đ¾Đ³Đ¾ Đ¸Đ¼ĐµĐ½Đ¸ Ñ„Đ°Đ¹Đ»Đ°. - - Recent Places - + + My Computer + ĐœĐ¾Đ¹ ĐºĐ¾Đ¼Đ¿ÑŒÑÑ‚ĐµÑ€ - + &Rename - &ĐŸĐµÑ€ĐµĐ¸Đ¼ĐµĐ½Đ¾Đ²Đ°Ñ‚ÑŒ + &ĐŸĐµÑ€ĐµĐ¸Đ¼ĐµĐ½Đ¾Đ²Đ°Ñ‚ÑŒ &Delete - &Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ + &Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ Show &hidden files - ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ &ÑĐºÑ€Ñ‹Ñ‚Ñ‹Đµ Ñ„Đ°Đ¹Đ»Ñ‹ + ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ ÑĐºÑ€&Ñ‹Ñ‚Ñ‹Đµ Ñ„Đ°Đ¹Đ»Ñ‹ - - New Folder - ĐĐ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + + + Back + ĐĐ°Đ·Đ°Đ´ - - Find Directory - ĐĐ°Đ¹Ñ‚Đ¸ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + + + Parent Directory + Đ Đ¾Đ´Đ¸Ñ‚ĐµĐ»ÑŒÑĐºĐ¸Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ - - Directories - ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ¸ + + + List View + Đ¡Đ¿Đ¸ÑĐ¾Đº - - All Files (*.*) - Đ’Ñе Ñ„Đ°Đ¹Đ»Ñ‹ (*.*) + + + Detail View + ĐŸĐ¾Đ´Ñ€Đ¾Đ±Đ½Ñ‹Đ¹ Đ²Đ¸Đ´ - - - Directory: - ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³: + + + Files of type: + Đ¢Đ¸Đ¿Ñ‹ Ñ„Đ°Đ¹Đ»Đ¾Đ²: - - %1 already exists. -Do you want to replace it? - + + + Directory: + ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³: - + + %1 -File not found. -Please verify the correct file name was given. - +Directory not found. +Please verify the correct directory name was given. + %1 +ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³ Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½. +ĐŸÑ€Đ¾Đ²ĐµÑ€ÑŒÑ‚Đµ Đ¿Ñ€Đ°Đ²Đ¸Đ»ÑŒĐ½Đ¾ÑÑ‚ÑŒ Đ·Đ°Đ´Đ°Đ½Đ½Đ¾Đ³Đ¾ Đ¸Đ¼ĐµĐ½Đ¸ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ°. - - My Computer - + + '%1' is write protected. +Do you want to delete it anyway? + '%1' Đ·Đ°Ñ‰Đ¸Ñ‰Ñ‘Đ½ Đ¾Ñ‚ Đ·Đ°Đ¿Đ¸Ñи. +Đ’ÑÑ‘-Ñ€Đ°Đ²Đ½Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ? - - - Parent Directory - - + + Are sure you want to delete '%1'? + Đ’Ñ‹ ÑƒĐ²ĐµÑ€ĐµĐ½Ñ‹, Ñ‡Ñ‚Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ '%1'? + - - - Files of type: - + + Could not delete directory. + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³. - - - %1 -Directory not found. -Please verify the correct directory name was given. - + + Recent Places + ĐĐµĐ´Đ°Đ²Đ½Đ¸Đµ Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Ñ‹ - - '%1' is write protected. -Do you want to delete it anyway? - + + All Files (*.*) + Đ’Ñе Ñ„Đ°Đ¹Đ»Ñ‹ (*.*) + + + + Save As + Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ ĐºĐ°Đº + + + + Drive + ДиÑĐº + + + + + File + Đ¤Đ°Đ¹Đ» - Are sure you want to delete '%1'? - + File Folder + Match Windows Explorer + ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³ Ñ Ñ„Đ°Đ¹Đ»Đ°Đ¼Đ¸ - - Could not delete directory. - + + Folder + All other platforms + ĐĐ°Ñ‚Đ°Đ»Đ¾Đ³ - - Drive - + + Alias + Mac OS X Finder + ĐŸÑĐµĐ²Đ´Đ¾Đ½Đ¸Đ¼ - + + Shortcut + All other platforms + Đ¯Ñ€Đ»Ñ‹Đº + + + Unknown - + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ¾ + + + + Find Directory + ĐĐ°Đ¹Ñ‚Đ¸ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ - + Show - + ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ - - + + Forward - Đ’Đ¿ĐµÑ€ĐµĐ´ + Đ’Đ¿ĐµÑ€ĐµĐ´ - + + New Folder + ĐĐ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + + + &New Folder - + &ĐĐ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ - + &Choose - + &Đ’Ñ‹Đ±Ñ€Đ°Ñ‚ÑŒ - + Remove - + Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ - - + + File &name: - &Đ˜Đ¼Ñ Ñ„Đ°Đ¹Đ»Đ°: + &Đ˜Đ¼Ñ Ñ„Đ°Đ¹Đ»Đ°: - - + + Look in: - + ĐŸĐµÑ€ĐµĐ¹Ñ‚Đ¸ Đº: - - + + Create New Folder - Đ¡Đ¾Đ·Đ´Đ°Ñ‚ÑŒ Đ½Đ¾Đ²Ñ‹Đ¹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ + Đ¡Đ¾Đ·Đ´Đ°Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ QFileSystemModel - - %1 TB - - - - - %1 GB - - - - - %1 MB - - - - - %1 KB - - - - - %1 bytes - - - - + Invalid filename - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ Đ¸Đ¼Ñ Ñ„Đ°Đ¹Đ»Đ° <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. - + <b>Đ˜Đ¼Ñ "%1" Đ½Đµ Đ¼Đ¾Đ¶ĐµÑ‚ Đ±Ñ‹Ñ‚ÑŒ иÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Đ½Đ¾.</b><p>ĐŸĐ¾Đ¿Ñ€Đ¾Đ±ÑƒĐ¹Ñ‚Đµ иÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ÑŒ Đ¸Đ¼Ñ Đ¼ĐµĐ½ÑŒÑˆĐµĐ¹ Đ´Đ»Đ¸Đ½Ñ‹ и/или без ÑĐ¸Đ¼Đ²Đ¾Đ»Đ¾Đ² Đ¿ÑƒĐ½ĐºÑ‚ÑƒĐ°Ñ†Đ¸Đ¸. Name - Đ˜Đ¼Ñ + Đ˜Đ¼Ñ Size - Đ Đ°Đ·Đ¼ĐµÑ€ + Đ Đ°Đ·Đ¼ĐµÑ€ Kind Match OS X Finder - + Вид Type All other platforms - Đ¢Đ¸Đ¿ + Đ¢Đ¸Đ¿ Date Modified - + Đ”Đ°Ñ‚Đ° Đ¸Đ·Đ¼ĐµĐ½ĐµĐ½Đ¸Ñ - + My Computer - + ĐœĐ¾Đ¹ ĐºĐ¾Đ¼Đ¿ÑŒÑÑ‚ĐµÑ€ Computer - + ĐĐ¾Đ¼Đ¿ÑŒÑÑ‚ĐµÑ€ + + + + + %1 TB + %1 Đ¢Đ± + + + + + %1 GB + %1 Гб + + + + + %1 MB + %1 ĐœĐ± + + + + + %1 KB + %1 Đб + + + + + %1 bytes + %1 Đ±Đ°Đ¹Ñ‚ @@ -1728,70 +1750,70 @@ Do you want to delete it anyway? Normal - + ĐĐ±Ñ‹Ñ‡Đ½Ñ‹Đ¹ Bold - + Đ–Đ¸Ñ€Đ½Ñ‹Đ¹ Demi Bold - + Đ¡Ñ€ĐµĐ½Đ´Đ½ĐµĐ¹ Đ¶Đ¸Ñ€Đ½Đ¾ÑÑ‚Đ¸ Black - + Đ§Ñ‘Ñ€Đ½Ñ‹Đ¹ Demi - + Đ¡Ñ€ĐµĐ´Đ½Đ¸Đ¹ Light - + Đ›Ñ‘Đ³ĐºĐ¸Đ¹ Italic - + ĐурÑĐ¸Đ² Oblique - + ĐĐ°ĐºĐ»Đ¾Đ½Đ½Ñ‹Đ¹ Any - + Đ›ÑĐ±Đ°Ñ Latin - + Đ›Đ°Ñ‚Đ¸Đ½Đ¸Ñ†Đ° Greek - + Đ“Ñ€ĐµÑ‡ĐµÑĐºĐ¸Đ¹ Cyrillic - + ĐĐ¸Ñ€Đ¸Đ»Đ»Đ¸Ñ†Đ° @@ -1949,7 +1971,7 @@ Do you want to delete it anyway? Font st&yle - &Đ¡Ñ‚Đ¸Đ»ÑŒ ÑˆÑ€Đ¸Ñ„Ñ‚Đ° + Đ¡Ñ‚&Đ¸Đ»ÑŒ ÑˆÑ€Đ¸Ñ„Ñ‚Đ° @@ -1964,12 +1986,12 @@ Do you want to delete it anyway? Stri&keout - &ĐŸĐµÑ€ĐµÑ‡ĐµÑ€ĐºĐ¸Đ²Đ°Ñ‚ÑŒ + Đ—Đ°Ñ‡Ñ‘Ñ€&ĐºĐ½ÑƒÑ‚Ñ‹Đ¹ &Underline - ĐŸ&Đ¾Đ´Ñ‡ĐµÑ€ĐºĐ¸Đ²Đ°Ñ‚ÑŒ + ĐŸ&Đ¾Đ´Ñ‡Ñ‘Ñ€ĐºĐ½ÑƒÑ‚Ñ‹Đ¹ @@ -1977,74 +1999,59 @@ Do you want to delete it anyway? ĐŸÑ€Đ¸Đ¼ĐµÑ€ - - - Select Font - Đ’Ñ‹Đ±Ñ€Đ°Ñ‚ÑŒ ÑˆÑ€Đ¸Ñ„Ñ‚ + + Wr&iting System + &Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° Đ¿Đ¸ÑÑŒĐ¼Đ° - - Wr&iting System - + + + Select Font + Đ’Ñ‹Đ±ĐµÑ€Đ¸Ñ‚Đµ ÑˆÑ€Đ¸Ñ„Ñ‚ QFtp - - Host %1 found - ĐĐ±Đ½Đ°Ñ€ÑƒĐ¶ĐµĐ½ ÑƒĐ·ĐµĐ» %1 - - - - Host found - Đ£Đ·ĐµĐ» Đ¾Đ±Đ½Đ°Ñ€ÑƒĐ¶ĐµĐ½ - - - - - - Connected to host %1 - Đ£ÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 - - - - Connected to host - Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ уÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½Đ¾ - - - - Connection to %1 closed - Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 Ñ€Đ°Đ·Đ¾Ñ€Đ²Đ°Đ½Đ¾ - - - - - - Connection closed - Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ€Đ°Đ·Đ¾Ñ€Đ²Đ°Đ½Đ¾ + + + Not connected + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Đ½Đµ уÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½Đ¾ - - + + Host %1 not found - Đ£Đ·ĐµĐ» %1 Đ½Đµ Đ¾Đ±Đ½Đ°Ñ€ÑƒĐ¶ĐµĐ½ + Đ£Đ·ĐµĐ» %1 Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½ Connection refused to host %1 - ĐÑ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 + Đ’ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 Đ¾Ñ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Connection timed out to host %1 - + Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 иÑÑ‚ĐµĐºĐ»Đ¾ + + + + + + Connected to host %1 + Đ£ÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 + + + + + Connection refused for data connection + ĐÑ‚ĐºĐ°Đ· Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ Đ´Đ»Ñ Đ¿ĐµÑ€ĐµĐ´Đ°Ñ‡Đ¸ Đ´Đ°Đ½Đ½Ñ‹Ñ… - + - + Unknown error ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° @@ -2054,7 +2061,7 @@ Do you want to delete it anyway? Connecting to host failed: %1 - ĐÑˆĐ¸Đ±ĐºĐ° ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Ñ Ñ ÑƒĐ·Đ»Đ¾Đ¼: + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ ÑĐ¾ĐµĐ´Đ¸Đ½Đ¸Ñ‚ÑŒÑÑ Ñ ÑƒĐ·Đ»Đ¾Đ¼: %1 @@ -2062,7 +2069,7 @@ Do you want to delete it anyway? Login failed: %1 - ĐÑˆĐ¸Đ±ĐºĐ° Đ²Ñ…Đ¾Đ´Đ° Đ² ÑиÑÑ‚ĐµĐ¼Ñƒ: + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ¾Đ²Đ°Ñ‚ÑŒÑÑ: %1 @@ -2070,7 +2077,7 @@ Do you want to delete it anyway? Listing directory failed: %1 - ĐÑˆĐ¸Đ±ĐºĐ° Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€Đ° ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ°: + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¿Ñ€Đ¾Ñ‡Đ¸Ñ‚Đ°Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³: %1 @@ -2078,7 +2085,7 @@ Do you want to delete it anyway? Changing directory failed: %1 - ĐÑˆĐ¸Đ±ĐºĐ° ÑĐ¼ĐµĐ½Ñ‹ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ°: + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ ÑĐ¼ĐµĐ½Đ¸Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³: %1 @@ -2086,7 +2093,7 @@ Do you want to delete it anyway? Downloading file failed: %1 - ĐÑˆĐ¸Đ±ĐºĐ° Đ·Đ°Đ³Ñ€ÑƒĐ·ĐºĐ¸ Ñ„Đ°Đ¹Đ»Đ°: + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ·Đ°Đ³Ñ€ÑƒĐ·Đ¸Ñ‚ÑŒ Ñ„Đ°Đ¹Đ»: %1 @@ -2094,7 +2101,7 @@ Do you want to delete it anyway? Uploading file failed: %1 - ĐÑˆĐ¸Đ±ĐºĐ° Đ¾Ñ‚Đ¿Ñ€Đ°Đ²ĐºĐ¸ Ñ„Đ°Đ¹Đ»Đ°: + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¾Ñ‚Đ³Ñ€ÑƒĐ·Đ¸Ñ‚ÑŒ Ñ„Đ°Đ¹Đ»: %1 @@ -2102,7 +2109,7 @@ Do you want to delete it anyway? Removing file failed: %1 - ĐÑˆĐ¸Đ±ĐºĐ° ÑƒĐ´Đ°Đ»ĐµĐ½Đ¸Ñ Ñ„Đ°Đ¹Đ»Đ°: + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ Ñ„Đ°Đ¹Đ»: %1 @@ -2110,7 +2117,7 @@ Do you want to delete it anyway? Creating directory failed: %1 - ĐÑˆĐ¸Đ±ĐºĐ° ÑĐ¾Đ·Đ´Đ°Đ½Đ¸Ñ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ°: + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ ÑĐ¾Đ·Đ´Đ°Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³: %1 @@ -2118,20 +2125,35 @@ Do you want to delete it anyway? Removing directory failed: %1 - ĐÑˆĐ¸Đ±ĐºĐ° ÑƒĐ´Đ°Đ»ĐµĐ½Đ¸Ñ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đ°: + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³: %1 - - - Not connected - ĐĐµÑ‚ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Ñ + + + + Connection closed + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Đ·Đ°ĐºÑ€Ñ‹Ñ‚Đ¾ - - - Connection refused for data connection - ĐÑ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ Đ¿ĐµÑ€ĐµĐ´Đ°Ñ‡Đ¸ Đ´Đ°Đ½Đ½Ñ‹Ñ… + + Host %1 found + Đ£Đ·ĐµĐ» %1 Đ½Đ°Đ¹Đ´ĐµĐ½ + + + + Connection to %1 closed + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ %1 Đ·Đ°ĐºÑ€Ñ‹Ñ‚Đ¾ + + + + Host found + Đ£Đ·ĐµĐ» Đ½Đ°Đ¹Đ´ĐµĐ½ + + + + Connected to host + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ @@ -2139,7 +2161,7 @@ Do you want to delete it anyway? Unknown error - ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° @@ -2149,12 +2171,12 @@ Do you want to delete it anyway? - + Host not found - + Đ£Đ·ĐµĐ» Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½ @@ -2162,331 +2184,331 @@ Do you want to delete it anyway? Unknown address type - + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Ñ‹Đ¹ Ñ‚Đ¸Đ¿ Đ°Đ´Ñ€ĐµÑĐ° Unknown error - ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° QHttp - - - Connection refused - ĐÑ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ - - - - - - Host %1 not found - Đ£Đ·ĐµĐ» %1 Đ½Đµ Đ¾Đ±Đ½Đ°Ñ€ÑƒĐ¶ĐµĐ½ + + + + + Unknown error + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° - - - Wrong content length - ĐĐµĐ²ĐµÑ€Đ½Đ°Ñ Đ´Đ»Đ¸Đ½Đ° Đ´Đ°Đ½Đ½Ñ‹Ñ… + + + Request aborted + Đ—Đ°Đ¿Ñ€Đ¾Ñ Đ¿Ñ€ĐµÑ€Đ²Đ°Đ½ - - HTTPS connection requested but SSL support not compiled in - + + + No server set to connect to + Đе ÑƒĐºĐ°Đ·Đ°Đ½ ÑĐµÑ€Đ²ĐµÑ€ Đ´Đ»Ñ Đ¿Đ¾Đ´ĐºĐ»ÑÑ‡ĐµĐ½Đ¸Ñ - - - - - HTTP request failed - ĐÑˆĐ¸Đ±ĐºĐ° HTTP-Đ·Đ°Đ¿Ñ€Đ¾ÑĐ° + + + Wrong content length + ĐĐµĐ²ĐµÑ€Đ½Đ°Ñ Đ´Đ»Đ¸Đ½Đ° ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đ³Đ¾ - - Host %1 found - ĐĐ±Đ½Đ°Ñ€ÑƒĐ¶ĐµĐ½ ÑƒĐ·ĐµĐ» %1 + + + Server closed connection unexpectedly + Đ¡ĐµÑ€Đ²ĐµÑ€ Đ½ĐµĐ¾Đ¶Đ¸Đ´Đ°Đ½Đ½Đ¾ Ñ€Đ°Đ·Đ¾Ñ€Đ²Đ°Đ» ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ - - Host found - Đ£Đ·ĐµĐ» Đ¾Đ±Đ½Đ°Ñ€ÑƒĐ¶ĐµĐ½ + + Unknown authentication method + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Ñ‹Đ¹ Đ¼ĐµÑ‚Đ¾Đ´ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ°Ñ†Đ¸Đ¸ - - Connected to host %1 - Đ£ÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 + + Error writing response to device + ĐÑˆĐ¸Đ±ĐºĐ° Đ·Đ°Đ¿Đ¸Ñи Đ¾Ñ‚Đ²ĐµÑ‚Đ° Đ½Đ° уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ - - Connected to host - Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ уÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½Đ¾ + + + Connection refused + ĐÑ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ - - Connection to %1 closed - Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 Ñ€Đ°Đ·Đ¾Ñ€Đ²Đ°Đ½Đ¾ + + + + Host %1 not found + Đ£Đ·ĐµĐ» %1 Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½ - - - Connection closed - Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ€Đ°Đ·Đ¾Ñ€Đ²Đ°Đ½Đ¾ + + + + + HTTP request failed + HTTP-Đ·Đ°Đ¿Ñ€Đ¾Ñ Đ½Đµ ÑƒĐ´Đ°Đ»ÑÑ - - - - - Unknown error - ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° + + + Invalid HTTP response header + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ HTTP-Đ·Đ°Đ³Đ¾Đ»Đ¾Đ²Đ¾Đº Đ¾Ñ‚Đ²ĐµÑ‚Đ° - - - Request aborted - Đ—Đ°Đ¿Ñ€Đ¾Ñ Đ¾Ñ‚Đ¼ĐµĐ½ĐµĐ½ + + + + + Invalid HTTP chunked body + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ HTTP-Ñ„Ñ€Đ°Đ³Đ¼ĐµĐ½Ñ‚Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ¸Đµ Đ´Đ°Đ½Đ½Ñ‹Ñ… - - - No server set to connect to - Đе Đ²Ñ‹Đ±Ñ€Đ°Đ½ ÑĐµÑ€Đ²ĐµÑ€ Đ´Đ»Ñ Đ¿Đ¾Đ´ĐºĐ»ÑÑ‡ĐµĐ½Đ¸Ñ + + Host %1 found + Đ£Đ·ĐµĐ» %1 Đ½Đ°Đ¹Đ´ĐµĐ½ - - - Server closed connection unexpectedly - ĐĐµĐ¾Đ¶Đ¸Đ´Đ°Đ½Đ½Ñ‹Đ¹ Ñ€Đ°Đ·Ñ€Ñ‹Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Ñ ÑĐµÑ€Đ²ĐµÑ€Đ¾Đ¼ + + Connected to host %1 + Đ£ÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 - - - Invalid HTTP response header - ĐŸĐ¾Đ»ÑƒÑ‡ĐµĐ½ Đ½ĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ HTTP-Đ·Đ°Đ³Đ¾Đ»Đ¾Đ²Đ¾Đº + + Connection to %1 closed + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ %1 Đ·Đ°ĐºÑ€Ñ‹Ñ‚Đ¾ - - Unknown authentication method - + + Host found + Đ£Đ·ĐµĐ» Đ½Đ°Đ¹Đ´ĐµĐ½ - - - - - Invalid HTTP chunked body - ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ HTTP-Đ¾Ñ‚Đ²ĐµÑ‚ + + Connected to host + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ ÑƒĐ·Đ»Đ¾Đ¼ уÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½Đ¾ - - Error writing response to device - + + + Connection closed + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Đ·Đ°ĐºÑ€Ñ‹Ñ‚Đ¾ - + Proxy authentication required - + Đ¢Ñ€ĐµĐ±ÑƒĐµÑ‚ÑÑ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ°Ñ†Đ¸Ñ Đ½Đ° Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đµ Authentication required - + Đ¢Ñ€ĐµĐ±ÑƒĐµÑ‚ÑÑ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ°Ñ†Đ¸Ñ Connection refused (or timed out) - + Đ’ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ Đ¾Ñ‚ĐºĐ°Đ·Đ°Đ½Đ¾ (или Đ²Ñ€ĐµĐ¼Ñ Đ¾Đ¶Đ¸Đ´Đ°Đ½Đ¸Ñ Đ¸ÑÑ‚ĐµĐºĐ»Đ¾) Proxy requires authentication - + ĐŸÑ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€ Ñ‚Ñ€ĐµĐ±ÑƒĐµÑ‚ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ°Ñ†Đ¸Ñ Host requires authentication - + Đ£Đ·ĐµĐ» Ñ‚Ñ€ĐµĐ±ÑƒĐµÑ‚ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ°Ñ†Đ¸Ñ Data corrupted - + Đ”Đ°Đ½Đ½Ñ‹Đµ Đ¿Đ¾Đ²Ñ€ĐµĐ¶Đ´ĐµĐ½Ñ‹ Unknown protocol specified - + Đ£ĐºĐ°Đ·Đ°Đ½ Đ½ĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Ñ‹Đ¹ Đ¿Ñ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» SSL handshake failed + + + HTTPS connection requested but SSL support not compiled in + Đ—Đ°Đ¿Ñ€Đ¾ÑˆĐµĐ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Đ¿Đ¾ Đ¿Ñ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ»Ñƒ HTTPS, Đ½Đ¾ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶ĐºĐ° SSL Đ½Đµ ÑĐºĐ¾Đ¼Đ¿Đ¸Đ»Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ° + QHttpSocketEngine Did not receive HTTP response from proxy - + Đе Đ¿Đ¾Đ»ÑƒÑ‡ĐµĐ½ HTTP-Đ¾Ñ‚Đ²ĐµÑ‚ Đ¾Ñ‚ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ° Error parsing authentication request from proxy - + ĐÑˆĐ¸Đ±ĐºĐ° Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° Đ·Đ°Đ¿Ñ€Đ¾ÑĐ° Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ°Ñ†Đ¸Đ¸ Đ¾Ñ‚ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ° Authentication required - + Đ¢Ñ€ĐµĐ±ÑƒĐµÑ‚ÑÑ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ°Ñ†Đ¸Ñ Proxy denied connection - + ĐŸÑ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€ Đ·Đ°Đ¿Ñ€ĐµÑ‚Đ¸Đ» ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Error communicating with HTTP proxy - + ĐÑˆĐ¸Đ±ĐºĐ° Đ¾Đ±Đ¼ĐµĐ½Đ° Đ´Đ°Đ½Đ½Ñ‹Đ¼Đ¸ Ñ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ¾Đ¼ HTTP Proxy server not found - + ĐŸÑ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€ Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½ Proxy connection refused - + Đ’ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ¾Đ¼ Đ¾Ñ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Proxy server connection timed out - + Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ¾Đ¼ иÑÑ‚ĐµĐºĐ»Đ¾ Proxy connection closed prematurely - + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ¾Đ¼ Đ½ĐµĐ¾Đ¶Đ¸Đ´Đ°Đ½Đ½Đ¾ Đ·Đ°ĐºÑ€Ñ‹Ñ‚Đ¾ QIBaseDriver - + Error opening database - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ±Đ°Đ·Ñƒ Đ´Đ°Đ½Đ½Ñ‹Ñ… Could not start transaction - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ½Đ°Ñ‡Đ°Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to commit transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to rollback transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºĐ°Ñ‚Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ QIBaseResult - + Unable to create BLOB - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Đ·Đ´Đ°Ñ‚ÑŒ BLOB Unable to write BLOB - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ·Đ°Đ¿Đ¸ÑĐ°Ñ‚ÑŒ BLOB Unable to open BLOB - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ BLOB Unable to read BLOB - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Ñ€Đ¾Ñ‡Đ¸Ñ‚Đ°Ñ‚ÑŒ BLOB - + Could not find array - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ½Đ°Đ¹Ñ‚Đ¸ Đ¼Đ°ÑÑĐ¸Đ² - + Could not get array data - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ½Đ°Đ¹Ñ‚Đ¸ Đ´Đ°Đ½Đ½Ñ‹Đµ Đ¼Đ°ÑÑĐ¸Đ²Đ° - + Could not get query info - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ½Đ°Đ¹Ñ‚Đ¸ Đ¸Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Ñ Đ¾ Đ·Đ°Đ¿Ñ€Đ¾Ñе Could not start transaction - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ½Đ°Ñ‡Đ°Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to commit transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Could not allocate statement - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ Ñ€ĐµÑурÑÑ‹ Đ´Đ»Ñ ÑĐ¾Đ·Đ´Đ°Đ½Đ¸Ñ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Ñ Could not prepare statement - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¿Đ¾Đ´Đ³Đ¾Ñ‚Đ¾Đ²Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Could not describe input statement - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¾Đ¿Đ¸ÑĐ°Ñ‚ÑŒ Đ²Ñ…Đ¾Đ´ÑÑ‰ĐµĐµ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Could not describe statement - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¾Đ¿Đ¸ÑĐ°Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to close statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ·Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to execute query - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Đ·Đ°Đ¿Ñ€Đ¾Ñ Could not fetch next item - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ ÑĐ»ĐµĐ´ÑƒÑÑ‰Đ¸Đ¹ ÑĐ»ĐµĐ¼ĐµĐ½Ñ‚ Could not get statement info - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ½Đ°Đ¹Ñ‚Đ¸ Đ¸Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Ñ Đ¾ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đ¸ @@ -2494,27 +2516,27 @@ Do you want to delete it anyway? Permission denied - + Đ”Đ¾ÑÑ‚ÑƒĐ¿ Đ·Đ°Đ¿Ñ€ĐµÑ‰Ñ‘Đ½ Too many open files - + Đ¡Đ»Đ¸ÑˆĐºĐ¾Đ¼ Đ¼Đ½Đ¾Đ³Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚Ñ‹Ñ… Ñ„Đ°Đ¹Đ»Đ¾Đ² No such file or directory - + Đ¤Đ°Đ¹Đ» или ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ Đ½Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚ No space left on device - + ĐĐµÑ‚ ÑĐ²Đ¾Đ±Đ¾Đ´Đ½Đ¾Đ³Đ¾ Đ¼ĐµÑÑ‚Đ° Đ½Đ° уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đµ - + Unknown error - ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° @@ -2545,7 +2567,7 @@ Do you want to delete it anyway? Enter a value: - + Đ£ĐºĐ°Đ¶Đ¸Ñ‚Đµ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ: @@ -2553,66 +2575,66 @@ Do you want to delete it anyway? Could not mmap '%1': %2 - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ mmap '%1': %2 Plugin verification data mismatch in '%1' - + ĐŸÑ€Đ¾Đ²ĐµÑ€Đ¾Ñ‡Đ½Đ°Ñ Đ¸Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Ñ Đ´Đ»Ñ Đ¼Đ¾Đ´ÑƒĐ»Ñ '%1' Đ½Đµ ÑĐ¾Đ²Đ¿Đ°Đ´Đ°ĐµÑ‚ Could not unmap '%1': %2 - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ unmap '%1': %2 The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] - + ĐœĐ¾Đ´ÑƒĐ»ÑŒ '%1' иÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐµÑ‚ Đ½ĐµÑĐ¾Đ¼ĐµÑÑ‚Đ¸Đ¼ÑƒÑ Đ±Đ¸Đ±Đ»Đ¸Đ¾Ñ‚ĐµĐºÑƒ Qt. (%2.%3.%4) [%5] The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" - + ĐŸĐ»Đ°Đ³Đ¸Đ½ '%1' иÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐµÑ‚ Đ½ĐµÑĐ¾Đ¼ĐµÑÑ‚Đ¸Đ¼ÑƒÑ Đ±Đ¸Đ±Đ»Đ¸Đ¾Ñ‚ĐµĐºÑƒ Qt. ĐĐ¶Đ¸Đ´Đ°ĐµÑ‚ÑÑ ĐºĐ»Ñч "%2", Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡ĐµĐ½ ĐºĐ»Ñч "%3" Unknown error - ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° The shared library was not found. - + Đ”Đ¸Đ½Đ°Đ¼Đ¸Ñ‡ĐµÑĐºĐ°Ñ Đ±Đ¸Đ±Đ»Đ¸Đ¾Ñ‚ĐµĐºĐ° Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½Đ°. The file '%1' is not a valid Qt plugin. - + Đ¤Đ°Đ¹Đ» '%1' - Đ½Đµ Đ¼Đ¾Đ¶ĐµÑ‚ Đ±Ñ‹Ñ‚ÑŒ ĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¼ Đ¼Đ¾Đ´ÑƒĐ»ĐµĐ¼ Qt. The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) - + ĐŸĐ»Đ°Đ³Đ¸Đ½ '%1' иÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐµÑ‚ Đ½ĐµÑĐ¾Đ¼ĐµÑÑ‚Đ¸Đ¼ÑƒÑ Đ±Đ¸Đ±Đ»Đ¸Đ¾Ñ‚ĐµĐºÑƒ Qt. (ĐĐµĐ»ÑŒĐ·Ñ ÑĐ¾Đ²Đ¼ĐµÑ‰Đ°Ñ‚ÑŒ Ñ€ĐµĐ»Đ¸Đ·Đ½Ñ‹Đµ и Đ¾Ñ‚Đ»Đ°Đ´Đ¾Ñ‡Đ½Ñ‹Đµ Đ±Đ¸Đ±Đ»Đ¸Đ¾Ñ‚ĐµĐºĐ¸.) Cannot load library %1: %2 - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ·Đ°Đ³Ñ€ÑƒĐ·Đ¸Ñ‚ÑŒ Đ±Đ¸Đ±Đ»Đ¸Đ¾Ñ‚ĐµĐºÑƒ %1: %2 Cannot unload library %1: %2 - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ³Ñ€ÑƒĐ·Đ¸Ñ‚ÑŒ Đ±Đ¸Đ±Đ»Đ¸Đ¾Ñ‚ĐµĐºÑƒ %1: %2 Cannot resolve symbol "%1" in %2: %3 - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Ñ€Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ ÑĐ¸Đ¼Đ²Đ¾Đ» "%1" Đ² %2: %3 @@ -2620,62 +2642,61 @@ Do you want to delete it anyway? &Undo - &ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ + &ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ &Redo - &ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ + &ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ Cu&t - &Đ’Ñ‹Ñ€ĐµĐ·Đ°Ñ‚ÑŒ + &Đ’Ñ‹Ñ€ĐµĐ·Đ°Ñ‚ÑŒ &Copy - &ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ + &ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ &Paste - Đ’&ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ + Đ’&ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ - - Select All - Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ²Ñе + + Delete + Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ - - Delete - Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ + + Select All + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ²Ñе QLocalServer - + %1: Name error - + %1: ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ Đ¸Đ¼Ñ %1: Permission denied - + %1: Đ”Đ¾ÑÑ‚ÑƒĐ¿ Đ·Đ°Đ¿Ñ€ĐµÑ‰Ñ‘Đ½ %1: Address in use - + %1: ĐĐ´Ñ€ĐµÑ Đ¸ÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐµÑ‚ÑÑ - %1: Unknown error %2 - + %1: ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° %2 @@ -2684,13 +2705,13 @@ Do you want to delete it anyway? %1: Connection refused - + %1: ĐÑ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ %1: Remote closed - + %1: Đ£Đ´Đ°Đ»Ñ‘Đ½Đ½Đ¾Đµ Đ·Đ°ĐºÑ€Ñ‹Ñ‚Đ¸Đµ @@ -2698,143 +2719,143 @@ Do you want to delete it anyway? %1: Invalid name - + %1: ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ Đ¸Đ¼Ñ %1: Socket access error - + %1: ĐÑˆĐ¸Đ±ĐºĐ° Đ¾Đ±Ñ€Đ°Ñ‰ĐµĐ½Đ¸Ñ Đº ÑĐ¾ĐºĐµÑ‚Ñƒ %1: Socket resource error - + %1: ĐÑˆĐ¸Đ±ĐºĐ° Đ²Ñ‹Đ´ĐµĐ»ĐµĐ½Đ¸Ñ Ñ€ĐµÑурÑĐ¾Đ² ÑĐ¾ĐºĐµÑ‚Đ° %1: Socket operation timed out - + %1: Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° Đ¾Đ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Ñ ÑĐ¾ĐºĐµÑ‚Đ¾Đ¼ иÑÑ‚ĐµĐºĐ»Đ¾ %1: Datagram too large - + %1: Đ”Đ°Ñ‚Đ°Đ³Ñ€Đ°Đ¼Đ¼Đ° ÑĐ»Đ¸ÑˆĐºĐ¾Đ¼ Đ±Đ¾Đ»ÑŒÑˆĐ°Ñ %1: Connection error - + %1: ĐÑˆĐ¸Đ±ĐºĐ° ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Ñ %1: The socket operation is not supported - + %1: ĐĐ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Ñ ÑĐ¾ĐºĐµÑ‚Đ¾Đ¼ Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ %1: Unknown error - + %1: ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° %1: Unknown error %2 - + %1: ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° %2 QMYSQLDriver - + Unable to open database ' - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ±Đ°Đ·Ñƒ Đ´Đ°Đ½Đ½Ñ‹Ñ… ' Unable to connect - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½Đ¸Ñ‚ÑŒÑÑ - + Unable to begin transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ½Đ°Ñ‡Đ°Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to commit transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to rollback transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºĐ°Ñ‚Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ QMYSQLResult - + Unable to fetch data - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ Đ´Đ°Đ½Đ½Ñ‹Đµ - + Unable to execute query - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Đ·Đ°Đ¿Ñ€Đ¾Ñ Unable to store result - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ Ñ€ĐµĐ·ÑƒĐ»ÑŒÑ‚Đ°Ñ‚ - + Unable to prepare statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ´Đ³Đ¾Ñ‚Đ¾Đ²Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ - + Unable to reset statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ±Ñ€Đ¾ÑĐ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ - + Unable to bind value - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Ñ€Đ¸Đ²ÑĐ·Đ°Ñ‚ÑŒ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ Unable to execute statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to bind outvalues - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Ñ€Đ¸Đ²ÑĐ·Đ°Ñ‚ÑŒ Ñ€ĐµĐ·ÑƒĐ»ÑŒÑ‚Đ¸Ñ€ÑƒÑÑ‰Đ¸Đµ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Ñ Unable to store statement results - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ Ñ€ĐµĐ·ÑƒĐ»ÑŒÑ‚Đ°Ñ‚ Đ²Ñ‹Đ¿Đ¾Đ»Đ½ĐµĐ½Đ¸Ñ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Ñ - + Unable to execute next query - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ ÑĐ»ĐµĐ´ÑƒÑÑ‰Đ¸Đ¹ Đ·Đ°Đ¿Ñ€Đ¾Ñ Unable to store next result - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ ÑĐ»ĐµĐ´ÑƒÑÑ‰Đ¸Đ¹ Ñ€ĐµĐ·ÑƒĐ»ÑŒÑ‚Đ°Ñ‚ @@ -2842,7 +2863,7 @@ Do you want to delete it anyway? (Untitled) - + (ĐĐµĐ¾Đ·Đ°Đ³Đ»Đ°Đ²Đ»ĐµĐ½Đ¾) @@ -2850,92 +2871,92 @@ Do you want to delete it anyway? %1 - [%2] - %1 - [%2] + %1 - [%2] Close - Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ Minimize - Đ¡Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ + ĐœĐ¸Đ½Đ¸Đ¼Đ¸Đ·Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Restore Down - Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ + Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ &Restore - &Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ + &Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ &Move - &ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ + &ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ &Size - &Đ Đ°Đ·Đ¼ĐµÑ€ + &Đ Đ°Đ·Đ¼ĐµÑ€ Mi&nimize - &Đ¡Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ + &ĐœĐ¸Đ½Đ¸Đ¼Đ¸Đ·Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Ma&ximize - Đ &Đ°Đ·Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ + Đ &Đ°ÑĐ¿Đ°Ñ…Đ½ÑƒÑ‚ÑŒ Stay on &Top - Đ’ÑĐµĐ³Đ´Đ° &Đ½Đ°Đ²ĐµÑ€Ñ…Ñƒ + ĐÑÑ‚Đ°Đ²Đ°Ñ‚ÑŒÑÑ &ÑĐ²ĐµÑ€Ñ…Ñƒ &Close - &Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + &Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ - [%1] - + - [%1] Maximize - Đ Đ°Đ·Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ + Đ Đ°ÑĐ¿Đ°Ñ…Đ½ÑƒÑ‚ÑŒ Unshade - + Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ из Đ·Đ°Đ³Đ¾Đ»Đ¾Đ²ĐºĐ° Shade - + Đ¡Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ Đ² Đ·Đ°Đ³Đ¾Đ»Đ¾Đ²Đ¾Đº Restore - + Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Help - Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° + Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° Menu - ĐœĐµĐ½Ñ + ĐœĐµĐ½Ñ @@ -2944,91 +2965,68 @@ Do you want to delete it anyway? Close - Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ Open - ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Execute - + Đ’Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ - QMenuBar - - About - Đ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đµ - - - Config - ĐĐ¾Đ½Ñ„Đ¸Đ³ÑƒÑ€Đ°Ñ†Đ¸Ñ - - - Preference - ĐĐ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ - - - Options - ĐŸĐ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Ñ‹ - - - Setting - ĐĐ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ - - - Setup - ĐĐ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ - - - Quit - Đ’Ñ‹Ñ…Đ¾Đ´ - + QMessageBox - Exit - Đ’Ñ‹Ñ…Đ¾Đ´ + + Help + Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° - - - QMessageBox - - + + OK - OK + Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ + + + + <h3>About Qt</h3><p>This program uses Qt version %1.</p><p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://www.qtsoftware.com/products/licensing">www.qtsoftware.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://www.qtsoftware.com/qt/">www.qtsoftware.com/qt</a> for more information.</p> + <h3>Đ Qt</h3><p>Đ”Đ°Đ½Đ½Đ°Ñ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đ° иÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐµÑ‚ Qt Đ²ĐµÑ€Ñии %1.</p><p>Qt - ÑÑ‚Đ¾ Đ¸Đ½ÑÑ‚Ñ€ÑƒĐ¼ĐµĐ½Ñ‚ Đ´Đ»Ñ Ñ€Đ°Đ·Ñ€Đ°Đ±Đ¾Ñ‚ĐºĐ¸ ĐºÑ€ÑÑĐ¿Đ»Đ°Ñ‚Ñ„Đ¾Ñ€Đ¼ĐµĐ½Đ½Ñ‹Ñ… Đ¿Ñ€Đ¸Đ»Đ¾Đ¶ĐµĐ½Đ¸Đ¹ Đ½Đ° C++.</p><p>Qt Đ¿Ñ€ĐµĐ´Đ¾ÑÑ‚Đ°Đ²Đ»ÑĐµÑ‚ Đ¿ĐµÑ€ĐµĐ½Đ¾ÑĐ¸Đ¼Đ¾ÑÑ‚ÑŒ Đ¼ĐµĐ¶Đ´Ñƒ MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux и Đ²ÑĐµĐ¼Đ¸ Đ¿Đ¾Đ¿ÑƒĐ»ÑÑ€Đ½Ñ‹Đ¼Đ¸ Đ²Đ°Ñ€Đ¸Đ°Đ½Ñ‚Đ°Đ¼Đ¸ ĐºĐ¾Đ¼Đ¼ĐµÑ€Ñ‡ĐµÑĐºĐ¾Đ¹ Unix. Đ¢Đ°ĐºĐ¶Đµ Qt Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° Đ´Đ»Ñ Đ²ÑÑ‚Ñ€Đ°Đ¸Đ²Đ°ĐµĐ¼Ñ‹Ñ… уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ² Đ² Đ²Đ¸Đ´Đµ Qt Đ´Đ»Ñ Embedded Linux и Qt Đ´Đ»Ñ Windows CE.</p><p>Qt Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° Đ¿Đ¾Đ´ Ñ‚Ñ€ĐµĐ¼Ñ Ñ€Đ°Đ·Đ»Đ¸Ñ‡Đ½Ñ‹Đ¼Đ¸ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸ÑĐ¼Đ¸, Ñ€Đ°Đ·Ñ€Đ°Đ±Đ¾Ñ‚Đ°Đ½Đ½Ñ‹Đ¼Đ¸ Đ´Đ»Ñ ÑƒĐ´Đ¾Đ²Đ»ĐµÑ‚Đ²Đ¾Ñ€ĐµĐ½Đ¸Ñ Ñ‚Ñ€ĐµĐ±Đ¾Đ²Đ°Đ½Đ¸Đ¹ Ñ€Đ°Đ·Đ»Đ¸Ñ‡Đ½Ñ‹Ñ… Đ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ĐµĐ»ĐµĐ¹.</p>Qt, Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ°Ñ Đ½Đ°ÑˆĐµĐ¹ ĐºĐ¾Đ¼Đ¼ĐµÑ€Ñ‡ĐµÑĐºĐ¾Đ¹ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸ĐµĐ¹, Đ¿Ñ€ĐµĐ´Đ½Đ°Đ·Đ½Đ°Ñ‡ĐµĐ½Đ° Đ´Đ»Ñ Ñ€Đ°Đ·Đ²Đ¸Ñ‚Đ¸Ñ Đ¿Ñ€Đ¾Đ¿Ñ€Đ¸ĐµÑ‚Đ°Ñ€Đ½Đ¾Đ³Đ¾/ĐºĐ¾Đ¼Đ¼ĐµÑ€Ñ‡ĐµÑĐºĐ¾Đ³Đ¾ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đ½Đ¾Đ³Đ¾ Đ¾Đ±ĐµÑĐ¿ĐµÑ‡ĐµĐ½Đ¸Ñ, ĐºĐ¾Đ³Đ´Đ° Đ’Ñ‹ Đ½Đµ Đ¶ĐµĐ»Đ°ĐµÑ‚Đµ Đ¿Ñ€ĐµĐ´Đ¾ÑÑ‚Đ°Đ²Đ»ÑÑ‚ÑŒ иÑÑ…Đ¾Đ´Đ½Ñ‹Đµ ĐºĐ¾Đ´Ñ‹ Ñ‚Ñ€ĐµÑ‚ÑŒĐ¸Đ¼ ÑÑ‚Đ¾Ñ€Đ¾Đ½Đ°Đ¼; ĐºĐ¾Đ¼Đ¼ĐµÑ€Ñ‡ĐµÑĐºĐ°Ñ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸Ñ Đ½Đµ ÑĐ¾Đ¾Ñ‚Đ²ĐµÑ‚ÑÑ‚Đ²ÑƒĐµÑ‚ уÑĐ»Đ¾Đ²Đ¸ÑĐ¼ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸Đ¹ GNU LGPL Đ²ĐµÑ€Ñии 2.1 или GNU GPL Đ²ĐµÑ€Ñии 3.0.</p><p>Qt Đ¿Đ¾Đ´ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸ĐµĐ¹ GNU LGPL Đ²ĐµÑ€Ñии 2.1 Đ¿Ñ€ĐµĐ´Đ½Đ°Đ·Đ½Đ°Ñ‡ĐµĐ½Đ° Đ´Đ»Ñ Ñ€Đ°Đ·Ñ€Đ°Đ±Đ¾Ñ‚ĐºĐ¸ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đ½Đ¾Đ³Đ¾ Đ¾Đ±ĐµÑĐ¿ĐµÑ‡ĐµĐ½Đ¸Ñ Ñ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚Ñ‹Đ¼ иÑÑ…Đ¾Đ´Đ½Ñ‹Đ¼ ĐºĐ¾Đ´Đ¾Đ¼ или ĐºĐ¾Đ¼Đ¼ĐµÑ€Ñ‡ĐµÑĐºĐ¾Đ³Đ¾ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đ½Đ¾Đ³Đ¾ Đ¾Đ±ĐµÑĐ¿ĐµÑ‡ĐµĐ½Đ¸Ñ Đ¿Ñ€Đ¸ ÑĐ¾Đ±Đ»ÑĐ´ĐµĐ½Đ¸Đ¸ ÑÑ€Đ¾ĐºĐ¾Đ² и уÑĐ»Đ¾Đ²Đ¸Đ¹ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸Đ¸ GNU LGPL Đ²ĐµÑ€Ñии 2.1.</p><p>Qt Đ¿Đ¾Đ´ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸ĐµĐ¹ GNU General Public License Đ²ĐµÑ€Ñии 3.0 Đ¿Ñ€ĐµĐ´Đ½Đ°Đ·Đ½Đ°Ñ‡ĐµĐ½Đ° Đ´Đ»Ñ Ñ€Đ°Đ·Ñ€Đ°Đ±Đ¾Ñ‚ĐºĐ¸ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đ½Ñ‹Ñ… Đ¿Ñ€Đ¸Đ»Đ¾Đ¶ĐµĐ½Đ¸Đ¹ Đ² Ñ‚ĐµÑ… ÑĐ»ÑƒÑ‡Đ°ÑÑ…, ĐºĐ¾Đ³Đ´Đ° Đ’Ñ‹ Ñ…Đ¾Ñ‚ĐµĐ»Đ¸ Đ±Ñ‹ иÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ÑŒ Ñ‚Đ°ĐºĐ¸Đµ Đ¿Ñ€Đ¸Đ»Đ¾Đ¶ĐµĐ½Đ¸Ñ Đ² ÑĐ¾Ñ‡ĐµÑ‚Đ°Đ½Đ¸Đ¸ Ñ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đ½Ñ‹Đ¼ Đ¾Đ±ĐµÑĐ¿ĐµÑ‡ĐµĐ½Đ¸ĐµĐ¼ Đ½Đ° уÑĐ»Đ¾Đ²Đ¸ÑÑ… Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸Đ¸ GNU GPL Ñ Đ²ĐµÑ€Ñии 3.0 или еÑли Đ’Ñ‹ Đ³Đ¾Ñ‚Đ¾Đ²Ñ‹ ÑĐ¾Đ±Đ»ÑĐ´Đ°Ñ‚ÑŒ уÑĐ»Đ¾Đ²Đ¸Ñ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸Đ¸ GNU GPL Đ²ĐµÑ€Ñии 3.0.</p><p>ĐĐ±Ñ€Đ°Ñ‚Đ¸Ñ‚ĐµÑÑŒ Đº <a href="http://www.qtsoftware.com/products/licensing">www.qtsoftware.com/products/licensing</a> Đ´Đ»Ñ Đ¾Đ±Đ·Đ¾Ñ€Đ° Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸Đ¹ Qt.</p><p>Copyright (C) 2009 ĐĐ¾Ñ€Đ¿Đ¾Ñ€Đ°Ñ†Đ¸Ñ Nokia и/или ĐµÑ‘ Đ´Đ¾Ñ‡ĐµÑ€Đ½Đ¸Đµ Đ¿Đ¾Đ´Ñ€Đ°Đ·Đ´ĐµĐ»ĐµĐ½Đ¸Ñ.</p><p>Qt - Đ¿Ñ€Đ¾Đ´ÑƒĐºÑ‚ Nokia. ĐĐ±Ñ€Đ°Ñ‚Đ¸Ñ‚ĐµÑÑŒ Đº <a href="http://www.qtsoftware.com/qt/">www.qtsoftware.com/qt</a> Đ´Đ»Ñ Đ¿Đ¾Đ»ÑƒÑ‡ĐµĐ½Đ¸Ñ Đ´Đ¾Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾Đ¹ Đ¸Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Đ¸.</p> - + About Qt - + Đ Qt - - Help - Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° + <p>This program uses Qt version %1.</p> + <p>Đ”Đ°Đ½Đ½Đ°Ñ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đ° иÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐµÑ‚ Qt Đ²ĐµÑ€Ñии %1.</p> - + Show Details... - + ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ Đ¿Đ¾Đ´Ñ€Đ¾Đ±Đ½Đ¾ÑÑ‚Đ¸... Hide Details... - + Đ¡ĐºÑ€Ñ‹Ñ‚ÑŒ Đ¿Đ¾Đ´Ñ€Đ¾Đ±Đ½Đ¾ÑÑ‚Đ¸... - - <h3>About Qt</h3><p>This program uses Qt version %1.</p><p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://www.qtsoftware.com/products/licensing">www.qtsoftware.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://www.qtsoftware.com/qt/">www.qtsoftware.com/qt</a> for more information.</p> - + <h3>About Qt</h3>%1<p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is a Nokia product. See <a href="http://qtsoftware.com/qt/">qtsoftware.com/qt/</a> for more information.</p> + <h3>Đ Qt</h3>%1<p>Qt - ÑÑ‚Đ¾ Đ¸Đ½ÑÑ‚Ñ€ÑƒĐ¼ĐµĐ½Ñ‚ Đ´Đ»Ñ Ñ€Đ°Đ·Ñ€Đ°Đ±Đ¾Ñ‚Ñ‡ĐºĐ¸ ĐºÑ€ÑÑĐ¿Đ»Đ°Ñ‚Ñ„Đ¾Ñ€Đ¼ĐµĐ½Đ½Ñ‹Ñ… Đ¿Ñ€Đ¸Đ»Đ¾Đ¶ĐµĐ½Đ¸Đ¹ Đ½Đ° C++.</p><p>Qt Đ¿Ñ€ĐµĐ´Đ¾ÑÑ‚Đ°Đ²Đ»ÑĐµÑ‚ Đ¿ĐµÑ€ĐµĐ½Đ¾ÑĐ¸Đ¼Đ¾ÑÑ‚ÑŒ Đ¼ĐµĐ¶Đ´Ñƒ MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux и Đ²ÑĐµĐ¼Đ¸ Đ¿Đ¾Đ¿ÑƒĐ»ÑÑ€Đ½Ñ‹Đ¼Đ¸ Đ²Đ°Ñ€Đ¸Đ°Đ½Ñ‚Đ°Đ¼Đ¸ ĐºĐ¾Đ¼Đ¼ĐµÑ€Ñ‡ĐµÑĐºĐ¾Đ¹ Unix. Đ¢Đ°ĐºĐ¶Đµ Qt Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° Đ´Đ»Ñ Đ²ÑÑ‚Ñ€Đ°Đ¸Đ²Đ°ĐµĐ¼Ñ‹Ñ… уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ² Đ² Đ²Đ¸Đ´Đµ Qt for Embedded Linux и Qt for Windows CE.</p><p>Qt - Đ¿Ñ€Đ¾Đ´ÑƒĐºÑ‚ Nokia. ĐĐ±Ñ€Đ°Ñ‚Đ¸Ñ‚ĐµÑÑŒ Đº <a href="http://qtsoftware.com/qt/">qtsoftware.com/qt/</a> Đ´Đ»Ñ Đ¿Đ¾Đ»ÑƒÑ‡ĐµĐ½Đ¸Ñ Đ´Đ¾Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾Đ¹ Đ¸Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Đ¸.</p> + + + <p>This program uses Qt Open Source Edition version %1.</p><p>Qt Open Source Edition is intended for the development of Open Source applications. You need a commercial Qt license for development of proprietary (closed source) applications.</p><p>Please see <a href="http://qtsoftware.com/company/model/">qtsoftware.com/company/model/</a> for an overview of Qt licensing.</p> + <p>Đ”Đ°Đ½Đ½Đ°Ñ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đ° иÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐµÑ‚ Qt Open Source Edition Đ²ĐµÑ€Ñии %1.</p><p>Qt Open Source Edition Đ¿Ñ€ĐµĐ´Đ½Đ°Đ·Đ½Đ°Ñ‡ĐµĐ½Đ° Đ´Đ»Ñ Ñ€Đ°Đ·Ñ€Đ°Đ±Đ¾Ñ‚ĐºĐ¸ Open Source Đ¿Ñ€Đ¸Đ»Đ¾Đ¶ĐµĐ½Đ¸Đ¹. Đ”Đ»Ñ Ñ€Đ°Đ·Ñ€Đ°Đ±Đ¾Ñ‚ĐºĐ¸ Đ¿Ñ€Đ¾Đ¿Ñ€Đ¸ĐµÑ‚Đ°Ñ€Đ½Ñ‹Ñ… (Ñ Đ·Đ°ĐºÑ€Ñ‹Ñ‚Ñ‹Đ¼ иÑÑ…Đ¾Đ´Đ½Ñ‹Đ¼ ĐºĐ¾Đ´Đ¾Đ¼) Đ¿Ñ€Đ¸Đ»Đ¾Đ¶ĐµĐ½Đ¸Đ¹ Đ½ĐµĐ¾Đ±Ñ…Đ¾Đ´Đ¸Đ¼Đ° ĐºĐ¾Đ¼Đ¼ĐµÑ€Ñ‡ĐµÑĐºĐ°Ñ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸Ñ Qt.</p><p>ĐĐ±Ñ€Đ°Ñ‚Đ¸Ñ‚ĐµÑÑŒ Đº Đ¾Ñ„Đ¸Ñ†Đ¸Đ°Đ»ÑŒĐ½Đ¾ÑĐ¹ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Đµ <a href="http://qtsoftware.com/company/model/">qtsoftware.com/company/model/</a> Đ´Đ»Ñ Đ¾Đ·Đ½Đ°ĐºĐ¾Đ¼Đ»ĐµĐ½Đ¸Ñ Ñ Đ¼Đ¾Đ´ĐµĐ»ÑĐ¼Đ¸ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ¸Ñ Qt.</p> @@ -3057,132 +3055,132 @@ Do you want to delete it anyway? The remote host closed the connection - + Đ£Đ´Đ°Đ»Ñ‘Đ½Đ½Ñ‹Đ¹ ÑƒĐ·ĐµĐ» Đ·Đ°ĐºÑ€Ñ‹Đ» ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Network operation timed out - + Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° ÑĐµÑ‚ĐµĐ²ÑƒÑ Đ¾Đ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Đ¸ÑÑ‚ĐµĐºĐ»Đ¾ Out of resources - + ĐĐµĐ´Đ¾ÑÑ‚Đ°Ñ‚Đ¾Ñ‡Đ½Đ¾ Ñ€ĐµÑурÑĐ¾Đ² Unsupported socket operation - + ĐĐ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Ñ ÑĐ¾ĐºĐµÑ‚Đ¾Đ¼ Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ Protocol type not supported - + ĐŸÑ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ Invalid socket descriptor - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ деÑĐºÑ€Đ¸Đ¿Ñ‚Đ¾Ñ€ ÑĐ¾ĐºĐµÑ‚Đ° Network unreachable - + Đ¡ĐµÑ‚ÑŒ Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° Permission denied - + Đ”Đ¾ÑÑ‚ÑƒĐ¿ Đ·Đ°Đ¿Ñ€ĐµÑ‰Ñ‘Đ½ Connection timed out - + Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ иÑÑ‚ĐµĐºĐ»Đ¾ Connection refused - ĐÑ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ + ĐÑ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Đ² ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ The bound address is already in use - + ĐĐ´Ñ€ĐµÑ ÑƒĐ¶Đµ иÑĐ¿Đ¾Đ»ÑŒĐ·ÑƒĐµÑ‚ÑÑ The address is not available - + ĐĐ´Ñ€ĐµÑ Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿ĐµĐ½ The address is protected - + ĐĐ´Ñ€ĐµÑ Đ·Đ°Ñ‰Đ¸Ñ‰Ñ‘Đ½ Unable to send a message - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚Đ¿Ñ€Đ°Đ²Đ¸Ñ‚ÑŒ ÑĐ¾Đ¾Đ±Ñ‰ĐµĐ½Đ¸Đµ Unable to receive a message - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ ÑĐ¾Đ¾Đ±Ñ‰ĐµĐ½Đ¸Đµ Unable to write - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ·Đ°Đ¿Đ¸ÑĐ°Ñ‚ÑŒ Network error - + ĐÑˆĐ¸Đ±ĐºĐ° ÑĐµÑ‚Đ¸ Another socket is already listening on the same port - + Đ”Ñ€ÑƒĐ³Đ¾Đ¹ ÑĐ¾ĐºĐµÑ‚ ÑƒĐ¶Đµ Đ¿Ñ€Đ¾ÑĐ»ÑƒÑˆĐ¸Đ²Đ°ĐµÑ‚ ÑÑ‚Đ¾Ñ‚ Đ¿Đ¾Ñ€Ñ‚ Unable to initialize non-blocking socket - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¸Đ½Đ¸Ñ†Đ¸Đ°Đ»Đ¸Đ·Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Đ½Đµ-Đ±Đ»Đ¾Ñ‡Đ½Ñ‹Đ¹ ÑĐ¾ĐºĐµÑ‚ Unable to initialize broadcast socket - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¸Đ½Đ¸Ñ†Đ¸Đ°Đ»Đ¸Đ·Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ ÑˆĐ¸Ñ€Đ¾ĐºĐ¾Đ²ĐµÑ‰Đ°Ñ‚ĐµĐ»ÑŒĐ½Ñ‹Đ¹ ÑĐ¾ĐºĐµÑ‚ Attempt to use IPv6 socket on a platform with no IPv6 support - + ĐŸĐ¾Đ¿Ñ‹Ñ‚ĐºĐ° иÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ÑŒ IPv6 Đ½Đ° Đ¿Đ»Đ°Ñ‚Ñ„Đ¾Ñ€Đ¼Đµ, Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ÑÑ‰ĐµĐ¹ IPv6 Host unreachable - + Đ£Đ·ĐµĐ» Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿ĐµĐ½ Datagram was too large to send - + Đ”Đ°Ñ‚Đ°Đ³Ñ€Đ°Đ¼Đ¼Đ° ÑĐ»Đ¸ÑˆĐºĐ¾Đ¼ Đ±Đ¾Đ»ÑŒÑˆĐ°Ñ Đ´Đ»Ñ Đ¾Ñ‚Đ¿Ñ€Đ°Đ²ĐºĐ¸ Operation on non-socket - + ĐĐ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Ñ Đ½Đµ-ÑĐ¾ĐºĐµÑ‚Đ¾Đ¼ Unknown error - ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° The proxy type is invalid for this operation - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ Ñ‚Đ¸Đ¿ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ° Đ´Đ»Ñ Đ´Đ°Đ½Đ½Đ¾Đ¹ Đ¾Đ¿ĐµÑ€Đ°Ñ†Đ¸Đ¸ @@ -3190,195 +3188,212 @@ Do you want to delete it anyway? Error opening %1 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚Đ¸Ñ %1 + + + + QNetworkAccessDebugPipeBackend + + + Write error writing to %1: %2 + ĐÑˆĐ¸Đ±ĐºĐ° Đ·Đ°Đ¿Đ¸Ñи Đ² %1: %2 QNetworkAccessFileBackend - + Request for opening non-local file %1 - + Đ—Đ°Đ¿Ñ€Đ¾Ñ Đ½Đ° Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚Đ¸Đµ Ñ„Đ°Đ¹Đ»Đ° Đ²Đ½Đµ Ñ„Đ°Đ¹Đ»Đ¾Đ²Đ¾Đ¹ ÑиÑÑ‚ĐµĐ¼Ñ‹ %1 - + Error opening %1: %2 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚Đ¸Ñ %1: %2 - + Write error writing to %1: %2 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ·Đ°Đ¿Đ¸Ñи Đ² %1: %2 - + Cannot open %1: Path is a directory - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ %1: Đ£ĐºĐ°Đ·Đ°Đ½ Đ¿ÑƒÑ‚ÑŒ Đº ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Ñƒ Read error reading from %1: %2 - + ĐÑˆĐ¸Đ±ĐºĐ° Ñ‡Ñ‚ĐµĐ½Đ¸Ñ Đ¸Đ· %1: %2 QNetworkAccessFtpBackend - + No suitable proxy found - + ĐŸĐ¾Đ´Ñ…Đ¾Đ´ÑÑ‰Đ¸Đ¹ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€ Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½ Cannot open %1: is a directory - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ %1: Đ£ĐºĐ°Đ·Đ°Đ½ Đ¿ÑƒÑ‚ÑŒ Đº ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Ñƒ - + Logging in to %1 failed: authentication required - + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ %1 Đ½Đµ ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ: Ñ‚Ñ€ĐµĐ±ÑƒĐµÑ‚ÑÑ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ°Ñ†Đ¸Ñ Error while downloading %1: %2 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ² Đ¿Ñ€Đ¾Ñ†ĐµÑÑе Đ·Đ°Đ³Ñ€ÑƒĐ·ĐºĐ¸ %1: %2 Error while uploading %1: %2 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ² Đ¿Ñ€Đ¾Ñ†ĐµÑÑе Đ¾Ñ‚Đ³Ñ€ÑƒĐ·ĐºĐ¸ %1: %2 QNetworkAccessHttpBackend - + No suitable proxy found - + ĐŸĐ¾Đ´Ñ…Đ¾Đ´ÑÑ‰Đ¸Đ¹ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€ Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½ QNetworkReply - + Error downloading %1 - server replied: %2 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ·Đ°Đ³Ñ€ÑƒĐ·ĐºĐ¸ %1 - Đ¾Ñ‚Đ²ĐµÑ‚ ÑĐµÑ€Đ²ĐµÑ€Đ°: %2 - + Protocol "%1" is unknown - + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Ñ‹Đ¹ Đ¿Ñ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ» "%1" QNetworkReplyImpl - + Operation canceled - + ĐĐ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Đ¾Ñ‚Đ¼ĐµĐ½ĐµĐ½Đ° QOCIDriver - + Unable to logon - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ¾Đ²Đ°Ñ‚ÑŒÑÑ Unable to initialize QOCIDriver - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¸Đ½Đ¸Ñ†Đ¸Đ°Đ»Đ¸Đ·Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Unable to begin transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ½Đ°Ñ‡Đ°Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to commit transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to rollback transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºĐ°Ñ‚Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ QOCIResult - + Unable to bind column for batch execute - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Ñ€Đ¸Đ²ÑĐ·Đ°Ñ‚ÑŒ ÑÑ‚Đ¾Đ»Đ±ĐµÑ† Đ´Đ»Ñ Đ¿Đ°ĐºĐµÑ‚Đ½Đ¾Đ³Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½ĐµĐ½Đ¸Ñ Unable to execute batch statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Đ¿Đ°ĐºĐµÑ‚Đ½Đ¾Đµ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to goto next - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿ĐµÑ€ĐµĐ¹Ñ‚Đ¸ Đº ÑĐ»ĐµĐ´ÑƒÑÑ‰ĐµĐ¹ ÑÑ‚Ñ€Đ¾ĐºĐµ Unable to alloc statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Đ·Đ´Đ°Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to prepare statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ´Đ³Đ¾Ñ‚Đ¾Đ²Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ - + + Unable to get statement type + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Đ¿Ñ€ĐµĐ´ĐµĐ»Đ¸Ñ‚ÑŒ Ñ‚Đ¸Đ¿ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Ñ + + + Unable to bind value - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Ñ€Đ¸Đ²ÑĐ·Đ°Ñ‚ÑŒ Ñ€ĐµĐ·ÑƒĐ»ÑŒÑ‚Đ¸Ñ€ÑƒÑÑ‰Đ¸Đµ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Ñ + + + Unable to execute select statement + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ ÑƒÑ‚Đ²ĐµÑ€Đ¶Đ´ĐµĐ½Đ¸Đµ SELECT Unable to execute statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ QODBCDriver - + Unable to connect - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½Đ¸Ñ‚ÑŒÑÑ Unable to connect - Driver doesn't support all needed functionality - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½Đ¸Ñ‚ÑŒÑÑ - Đ”Ñ€Đ°Đ¹Đ²ĐµÑ€ Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Ñ‚Ñ€ĐµĐ±ÑƒĐµĐ¼Ñ‹Đ¹ Ñ„ÑƒĐ½ĐºÑ†Đ¸Đ¾Đ½Đ°Đ» Unable to disable autocommit - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ Đ°Đ²Ñ‚Đ¾Đ²Ñ‹Đ¿Đ¾Đ»Đ½ĐµĐ½Đ¸Đµ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Đ¸ Unable to commit transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to rollback transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºĐ°Ñ‚Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to enable autocommit - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ уÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Đ°Đ²Ñ‚Đ¾Đ²Ñ‹Đ¿Đ¾Đ»Đ½ĐµĐ½Đ¸Đµ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Đ¸ @@ -3387,50 +3402,50 @@ Do you want to delete it anyway? QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration - + QODBCResult::reset: ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ уÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ 'SQL_CURSOR_STATIC' Đ°Ñ‚Ñ€Đ¸Đ±ÑƒÑ‚Đ¾Đ¼ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ. ĐŸÑ€Đ¾Đ²ĐµÑ€ÑŒÑ‚Đµ Đ½Đ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ Đ´Ñ€Đ°Đ¹Đ²ĐµÑ€Đ° ODBC Unable to execute statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to fetch next - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ ÑĐ»ĐµĐ´ÑƒÑÑ‰ÑƒÑ ÑÑ‚Ñ€Đ¾ĐºÑƒ Unable to prepare statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ´Đ³Đ¾Ñ‚Đ¾Đ²Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to bind variable - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Ñ€Đ¸Đ²ÑĐ·Đ°Ñ‚ÑŒ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ Unable to fetch last - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ Đ¿Đ¾ÑĐ»ĐµĐ´Đ½ÑÑ ÑÑ‚Ñ€Đ¾ĐºÑƒ Unable to fetch - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ Đ´Đ°Đ½Đ½Ñ‹Đµ Unable to fetch first - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ Đ¿ĐµÑ€Đ²ÑƒÑ ÑÑ‚Ñ€Đ¾ĐºÑƒ Unable to fetch previous - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰ÑƒÑ ÑÑ‚Ñ€Đ¾ĐºÑƒ @@ -3438,61 +3453,58 @@ Do you want to delete it anyway? Home - Home + Operation not supported on %1 - + ĐĐ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ Đ´Đ»Ñ %1 Invalid URI: %1 - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ URI: %1 - Write error writing to %1: %2 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ·Đ°Đ¿Đ¸Ñи Đ² %1: %2 - Read error reading from %1: %2 - + ĐÑˆĐ¸Đ±ĐºĐ° Ñ‡Ñ‚ĐµĐ½Đ¸Ñ Đ¸Đ· %1: %2 - + Socket error on %1: %2 - + ĐÑˆĐ¸ĐºĐ° ÑĐ¾ĐºĐµÑ‚Đ° Đ´Đ»Ñ %1: %2 Remote host closed the connection prematurely on %1 - + Đ£Đ´Đ°Đ»Ñ‘Đ½Đ½Ñ‹Đ¹ ÑƒĐ·ĐµĐ» Đ½ĐµĐ¾Đ¶Đ¸Đ´Đ°Đ½Đ½Đ¾ Đ¿Ñ€ĐµÑ€Đ²Đ°Đ» ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Đ´Đ»Ñ %1 - Protocol error: packet of size 0 received - + ĐÑˆĐ¸Đ±ĐºĐ° Đ¿Ñ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ»Đ°: Đ¿Đ¾Đ»ÑƒÑ‡ĐµĐ½ Đ¿Đ°ĐºĐµÑ‚ Đ½ÑƒĐ»ĐµĐ²Đ¾Đ³Đ¾ Ñ€Đ°Đ·Đ¼ĐµÑ€Đ° No host name given - + Đ˜Đ¼Ñ ÑƒĐ·Đ»Đ° Đ½Đµ Đ·Đ°Đ´Đ°Đ½Đ¾ QPPDOptionsModel - + Name - Đ˜Đ¼Ñ + Đ˜Đ¼Ñ Value - + Đ—Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ @@ -3500,32 +3512,32 @@ Do you want to delete it anyway? Unable to connect - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾ĐµĐ´Đ¸Đ½Đ¸Ñ‚ÑŒÑÑ Could not begin transaction - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ½Đ°Ñ‡Đ°Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Could not commit transaction - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Could not rollback transaction - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¾Ñ‚ĐºĐ°Ñ‚Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to subscribe - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ´Đ¿Đ¸ÑĐ°Ñ‚ÑŒÑÑ Unable to unsubscribe - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚Đ¿Đ¸ÑĐ°Ñ‚ÑŒÑÑ @@ -3533,12 +3545,12 @@ Do you want to delete it anyway? Unable to create query - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Đ·Đ´Đ°Ñ‚ÑŒ Đ·Đ°Đ¿Ñ€Đ¾Ñ Unable to prepare statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ´Đ³Đ¾Ñ‚Đ¾Đ²Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ @@ -3546,102 +3558,106 @@ Do you want to delete it anyway? Centimeters (cm) - + Đ¡Đ°Đ½Ñ‚Đ¸Đ¼ĐµÑ‚Ñ€Ñ‹ (cm) Millimeters (mm) - + ĐœĐ¸Đ»Đ»Đ¸Đ¼ĐµÑ‚Ñ€Ñ‹ (mm) Inches (in) - + Đ”ÑĐ¹Đ¼Ñ‹ (in) Points (pt) - + Đ¢Đ¾Ñ‡ĐºĐ¸ (pt) - + Form - + Đ¤Đ¾Ñ€Đ¼Đ° - + Paper - + Đ‘ÑƒĐ¼Đ°Đ³Đ° - + Page size: - + Đ Đ°Đ·Đ¼ĐµÑ€ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñ‹: - + Width: - + Đ¨Đ¸Ñ€Đ¸Đ½Đ°: - + Height: - + Đ’Ñ‹ÑĐ¾Ñ‚Đ°: - + Paper source: - + Đ˜ÑÑ‚Đ¾Ñ‡Đ½Đ¸Đº Đ±ÑƒĐ¼Đ°Đ³Đ¸: - + Orientation - + ĐÑ€Đ¸ĐµĐ½Ñ‚Đ°Ñ†Đ¸Ñ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñ‹ - + Portrait - ĐŸĐ¾Ñ€Ñ‚Ñ€ĐµÑ‚ + ĐĐ½Đ¸Đ¶Đ½Đ°Ñ - + Landscape - ĐĐ»ÑŒĐ±Đ¾Đ¼ + ĐĐ»ÑŒĐ±Đ¾Đ¼Đ½Đ°Ñ - + Reverse landscape - + ĐŸĐµÑ€ĐµĐ²Ñ‘Ñ€Đ½ÑƒÑ‚Đ°Ñ Đ°Đ»ÑŒĐ±Đ¾Đ¼Đ½Đ°Ñ - + Reverse portrait - + ĐŸĐµÑ€ĐµĐ²Ñ‘Ñ€Đ½ÑƒÑ‚Đ°Ñ ĐºĐ½Đ¸Đ¶Đ½Đ°Ñ - + Margins - + ĐŸĐ¾Đ»Ñ - + + top margin - + Đ²ĐµÑ€Ñ…Đ½ĐµĐµ Đ¿Đ¾Đ»Đµ - + + left margin - + Đ›ĐµĐ²Đ¾Đµ Đ¿Đ¾Đ»Đµ - + + right margin - + Đ¿Ñ€Đ°Đ²Đ¾Đµ Đ¿Đ¾Đ»Đµ - + + bottom margin - + ĐĐ¸Đ¶Đ½ĐµĐµ Đ¿Đ¾Đ»Đµ @@ -3649,12 +3665,12 @@ Do you want to delete it anyway? Unknown error - ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° The plugin was not loaded. - + ĐœĐ¾Đ´ÑƒĐ»ÑŒ Đ½Đµ Đ±Ñ‹Đ» Đ·Đ°Đ³Ñ€ÑƒĐ¶ĐµĐ½. @@ -3662,13 +3678,13 @@ Do you want to delete it anyway? locally connected - Đ»Đ¾ĐºĐ°Đ»ÑŒĐ½Ñ‹Đ¹ + ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¾ Đ»Đ¾ĐºĐ°Đ»ÑŒĐ½Đ¾ Aliases: %1 - ĐлиаÑÑ‹: %1 + ĐŸÑĐµĐ²Đ´Đ¾Đ½Đ¸Đ¼Ñ‹: %1 @@ -3677,54 +3693,7 @@ Do you want to delete it anyway? Đ½ĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ¾ - - OK - OK - - - Cancel - ĐÑ‚Đ¼ĐµĐ½Đ° - - - Print in color if available - Đ¦Đ²ĐµÑ‚Đ½Đ°Ñ Đ¿ĐµÑ‡Đ°Ñ‚ÑŒ - - - Printer - ĐŸÑ€Đ¸Đ½Ñ‚ĐµÑ€ - - - - Print all - ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ²Ñе - - - - Print range - ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ´Đ¸Đ°Đ¿Đ°Đ·Đ¾Đ½ - - - Print last page first - ĐĐ°Ñ‡Đ°Ñ‚ÑŒ Ñ Đ¿Đ¾ÑĐ»ĐµĐ´Đ½ĐµĐ¹ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñ‹ - - - Number of copies: - ЧиÑĐ»Đ¾ ĐºĐ¾Đ¿Đ¸Đ¹: - - - Paper format - Đ¤Đ¾Ñ€Đ¼Đ°Ñ‚ Đ±ÑƒĐ¼Đ°Đ³Đ¸ - - - Portrait - ĐŸĐ¾Ñ€Ñ‚Ñ€ĐµÑ‚ - - - Landscape - ĐĐ»ÑŒĐ±Đ¾Đ¼ - - - + A0 (841 x 1189 mm) A0 (841 x 1189 Đ¼Đ¼) @@ -3740,11 +3709,16 @@ Do you want to delete it anyway? - A3 (297 x 420 mm) - A3 (297 x 420 Đ¼Đ¼) + A3 (297 x 420 mm) + A3 (297 x 420 Đ¼Đ¼) + + + + A4 (210 x 297 mm, 8.26 x 11.7 inches) + A4 (210 x 297 Đ¼Đ¼, 8.26 x 11.7 Đ´ÑĐ¹Đ¼Đ¾Đ²) - + A5 (148 x 210 mm) A5 (148 x 210 Đ¼Đ¼) @@ -3794,7 +3768,12 @@ Do you want to delete it anyway? B4 (250 x 353 Đ¼Đ¼) - + + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B5 (176 x 250 Đ¼Đ¼, 6.93 x 9.84 Đ´ÑĐ¹Đ¼Đ¾Đ²) + + + B6 (125 x 176 mm) B6 (125 x 176 Đ¼Đ¼) @@ -3829,7 +3808,12 @@ Do you want to delete it anyway? DLE (110 x 220 Đ¼Đ¼) - + + Executive (7.5 x 10 inches, 191 x 254 mm) + Executive (191 x 254 Đ¼Đ¼, 7.5 x 10 Đ´ÑĐ¹Đ¼Đ¾Đ²) + + + Folio (210 x 330 mm) Folio (210 x 330 Đ¼Đ¼) @@ -3839,88 +3823,87 @@ Do you want to delete it anyway? Ledger (432 x 279 Đ¼Đ¼) - - Tabloid (279 x 432 mm) - Tabloid (279 x 432 Đ¼Đ¼) - - - US Common #10 Envelope (105 x 241 mm) - ĐĐ¾Đ½Đ²ĐµÑ€Ñ‚ US #10 (105x241 Đ¼Đ¼) - - - - A4 (210 x 297 mm, 8.26 x 11.7 inches) - + Legal (8.5 x 14 inches, 216 x 356 mm) + Legal (216 x 356 Đ¼Đ¼, 8.5 x 14 Đ´ÑĐ¹Đ¼Đ¾Đ²) - - B5 (176 x 250 mm, 6.93 x 9.84 inches) - + + Letter (8.5 x 11 inches, 216 x 279 mm) + Letter (216 x 279 Đ¼Đ¼, 8.5 x 11 Đ´ÑĐ¹Đ¼Đ¾Đ²) - - Executive (7.5 x 10 inches, 191 x 254 mm) - + + Tabloid (279 x 432 mm) + Tabloid (279 x 432 Đ¼Đ¼) - - Legal (8.5 x 14 inches, 216 x 356 mm) - + + US Common #10 Envelope (105 x 241 mm) + ĐĐ¾Đ½Đ²ĐµÑ€Ñ‚ US #10 (105x241 Đ¼Đ¼) - - Letter (8.5 x 11 inches, 216 x 279 mm) - + + OK + Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ Print - Print - - - File - Đ¤Đ°Đ¹Đ» + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Print To File ... - + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ² Ñ„Đ°Đ¹Đ» ... + + + + Print range + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ´Đ¸Đ°Đ¿Đ°Đ·Đ¾Đ½ + + + + Print all + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ²Ñе - + File %1 is not writable. Please choose a different file name. - + %1 Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿ĐµĐ½ Đ´Đ»Ñ Đ·Đ°Đ¿Đ¸Ñи. +Đ’Ñ‹Đ±ĐµÑ€Đ¸Ñ‚Đµ Đ´Ñ€ÑƒĐ³Đ¾Đµ Đ¸Đ¼Ñ Ñ„Đ°Đ¹Đ»Đ°. %1 already exists. Do you want to overwrite it? - + %1 ÑƒĐ¶Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚. +Đ¥Đ¾Ñ‚Đ¸Ñ‚Đµ Đ·Đ°Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ ĐµĐ³Đ¾? - + File exists - + Đ¤Đ°Đ¹Đ» ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚ <qt>Do you want to overwrite it?</qt> - + <qt>Đ¥Đ¾Ñ‚Đ¸Ñ‚Đµ Đ·Đ°Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ?</qt> Print selection - + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ²Ñ‹Đ´ĐµĐ»ĐµĐ½Đ½Đ¾Đµ %1 is a directory. Please choose a different file name. - + %1 - ÑÑ‚Đ¾ ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³. +Đ’Ñ‹Đ±ĐµÑ€Đ¸Ñ‚Đµ Đ´Ñ€ÑƒĐ³Đ¾Đµ Đ¸Đ¼Ñ Ñ„Đ°Đ¹Đ»Đ°. @@ -4075,48 +4058,48 @@ Please choose a different file name. Custom - + ĐŸÑ€Đ¾Đ¸Đ·Đ²Đ¾Đ»ÑŒĐ½Ñ‹Đ¹ - + &Options >> - + &ĐŸĐ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Ñ‹ >> &Print - + &ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ &Options << - + &ĐŸĐ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Ñ‹ << Print to File (PDF) - + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ² Ñ„Đ°Đ¹Đ» (PDF) Print to File (Postscript) - + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ² Ñ„Đ°Đ¹Đ» (Postscript) - + Local file - + Đ›Đ¾ĐºĐ°Đ»ÑŒĐ½Ñ‹Đ¹ Ñ„Đ°Đ¹Đ» Write %1 file - + Đ—Đ°Đ¿Đ¸ÑÑŒ %1 Ñ„Đ°Đ¹Đ» The 'From' value cannot be greater than the 'To' value. - + Đ—Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ 'Đ¾Ñ‚' Đ½Đµ Đ¼Đ¾Đ¶ĐµÑ‚ Đ±Ñ‹Ñ‚ÑŒ Đ±Đ¾Đ»ÑŒÑˆĐµ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Ñ 'Đ´Đ¾'. @@ -4125,345 +4108,333 @@ Please choose a different file name. Page Setup - + Đ¡Đ²Đ¾Đ¹ÑÑ‚Đ²Đ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñ‹ - + %1% - + %1% - + Print Preview - + ĐŸÑ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ Đ¿ĐµÑ‡Đ°Ñ‚Đ¸ - + Next page - + Đ¡Đ»ĐµĐ´ÑƒÑÑ‰Đ°Ñ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Đ° Previous page - + ĐŸÑ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰Đ°Ñ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Đ° First page - + ĐŸĐµÑ€Đ²Đ°Ñ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Đ° Last page - + ĐŸĐ¾ÑĐ»ĐµĐ´Đ½ÑÑ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Đ° Fit width - + ĐŸĐ¾ ÑˆĐ¸Ñ€Đ¸Đ½Đµ Fit page - + ĐĐ° Đ²ÑÑ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Zoom in - + Đ£Đ²ĐµĐ»Đ¸Ñ‡Đ¸Ñ‚ÑŒ Zoom out - + Đ£Đ¼ĐµĐ½ÑŒÑˆĐ¸Ñ‚ÑŒ Portrait - ĐŸĐ¾Ñ€Ñ‚Ñ€ĐµÑ‚ + ĐĐ½Đ¸Đ¶Đ½Đ°Ñ Landscape - ĐĐ»ÑŒĐ±Đ¾Đ¼ + ĐĐ»ÑŒĐ±Đ¾Đ¼Đ½Đ°Ñ Show single page - + ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ Đ¾Đ´Đ½Ñƒ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Show facing pages - + ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ Ñ‚Đ¸Ñ‚ÑƒĐ»ÑŒĐ½Ñ‹Đµ ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñ‹ Show overview of all pages - + ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ Đ¾Đ±Đ·Đ¾Ñ€ Đ²ÑĐµÑ… ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ† Print - Print + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Page setup - + Đ¡Đ²Đ¾Đ¹ÑÑ‚Đ²Đ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñ‹ - Close - Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ - + Export to PDF - + Đ­ĐºÑĐ¿Đ¾Ñ€Ñ‚ Đ² PDF Export to PostScript - - - - - QPrintPropertiesDialog - - Save - Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ - - - OK - OK + Đ­ĐºÑĐ¿Đ¾Ñ€Ñ‚ Đ² Postscript QPrintPropertiesWidget - + Form - + Đ¤Đ¾Ñ€Đ¼Đ° - + Page - + Đ¡Ñ‚Ñ€Đ°Đ½Đ¸Ñ†Đ° - + Advanced - + Đ”Đ¾Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾ QPrintSettingsOutput - + Form - + Đ¤Đ¾Ñ€Đ¼Đ° - + Copies - + ĐĐ¾Đ¿Đ¸Đ¸ - + Print range - ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ´Đ¸Đ°Đ¿Đ°Đ·Đ¾Đ½ + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ´Đ¸Đ°Đ¿Đ°Đ·Đ¾Đ½ - + Print all - ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ²Ñе + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ Đ²Ñе - + Pages from - + Đ¡Ñ‚Ñ€Đ°Đ½Đ¸Ñ†Ñ‹ Đ¾Ñ‚ - + to - + Đ´Đ¾ - + Selection - + Đ’Ñ‹Đ´ĐµĐ»ĐµĐ½Đ½Ñ‹Đµ - + Output Settings - + ĐĐ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ Đ²Ñ‹Đ²Đ¾Đ´Đ° - + Copies: - + ĐĐ¾Đ»Đ¸Ñ‡ĐµÑÑ‚Đ²Đ¾ ĐºĐ¾Đ¿Đ¸Đ¹: - + Collate - + Đ Đ°Đ·Đ¾Đ±Ñ€Đ°Ñ‚ÑŒ Đ¿Ñ€Đ¾ ĐºĐ¾Đ¿Đ¸ÑĐ¼ - + Reverse - + ĐĐ±Ñ€Đ°Ñ‚Đ½Ñ‹Đ¹ Đ¿Đ¾Ñ€ÑĐ´Đ¾Đº - + Options - ĐŸĐ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Ñ‹ + ĐŸĐ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Ñ‹ - + Color Mode - + Đ ĐµĐ¶Đ¸Đ¼ Ñ†Đ²ĐµÑ‚Đ° - + Color - + Đ¦Đ²ĐµÑ‚ - + Grayscale - + ĐÑ‚Ñ‚ĐµĐ½ĐºĐ¸ ÑĐµÑ€Đ¾Đ³Đ¾ - + Duplex Printing - + Đ”Đ²ÑƒÑÑ‚Đ¾Ñ€Đ¾Đ½Đ½ÑÑ Đ¿ĐµÑ‡Đ°Ñ‚ÑŒ - + None - + ĐĐµÑ‚ - + Long side - + ĐŸĐ¾ Đ´Đ»Đ¸Đ½Đ½Đ¾Đ¹ ÑÑ‚Đ¾Ñ€Đ¾Đ½Đµ - + Short side - + ĐŸĐ¾ ĐºĐ¾Ñ€Đ¾Ñ‚ĐºĐ¾Đ¹ ÑÑ‚Đ¾Ñ€Đ¾Đ½Đµ QPrintWidget - + Form - + Đ¤Đ¾Ñ€Đ¼Đ° - + Printer - ĐŸÑ€Đ¸Đ½Ñ‚ĐµÑ€ + ĐŸÑ€Đ¸Đ½Ñ‚ĐµÑ€ - + &Name: - + &Đ˜Đ¼Ñ: - + P&roperties - + Đ¡&Đ²Đ¾Đ¹ÑÑ‚Đ²Đ° - + Location: - + ĐŸĐ¾Đ»Đ¾Đ¶ĐµĐ½Đ¸Đµ: - + Preview - + ĐŸÑ€ĐµĐ´Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ - + Type: - + Đ¢Đ¸Đ¿: - + Output &file: - + Đ’Ñ‹Ñ…Đ¾Đ´Đ½Đ¾Đ¹ &Ñ„Đ°Đ¹Đ»: - + ... - + ... QProcess - + Could not open input redirection for reading - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ¿ĐµÑ€ĐµĐ½Đ°Đ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Đµ Đ²Đ²Đ¾Đ´Đ° Đ´Đ»Ñ Ñ‡Ñ‚ĐµĐ½Đ¸Ñ Could not open output redirection for writing - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ¿ĐµÑ€ĐµĐ½Đ°Đ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Đµ Đ²Ñ‹Đ²Đ¾Đ´Đ° Đ´Đ»Ñ Đ·Đ°Đ¿Đ¸Ñи - + Resource error (fork failure): %1 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ²Ñ‹Đ´ĐµĐ»ĐµĐ½Đ¸Ñ Ñ€ĐµÑурÑĐ¾Đ² (fork Đ½Đµ ÑƒĐ´Đ°Đ»ÑÑ): %1 - + Process operation timed out - + Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° Đ¾Đ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Ñ Đ¿Ñ€Đ¾Ñ†ĐµÑÑĐ¾Đ¼ иÑÑ‚ĐµĐºĐ»Đ¾ - + Error reading from process - + ĐÑˆĐ¸Đ±ĐºĐ° Đ¿Đ¾Đ»ÑƒÑ‡ĐµĐ½Đ¸Ñ Đ´Đ°Đ½Đ½Ñ‹Ñ… Đ¾Ñ‚ Đ¿Ñ€Đ¾Ñ†ĐµÑÑĐ° - + Error writing to process - + ĐÑˆĐ¸Đ±ĐºĐ° Đ¾Ñ‚Đ¿Ñ€Đ°Đ²ĐºĐ¸ Đ´Đ°Đ½Đ½Ñ‹Ñ… Đ¿Ñ€Đ¾Ñ†ĐµÑÑу - + Process crashed - + ĐŸÑ€Đ¾Ñ†ĐµÑÑ Đ·Đ°Đ²ĐµÑ€ÑˆĐ¸Đ»ÑÑ Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ¾Đ¹ - + No program defined - + ĐŸÑ€Đ¾Đ³Ñ€Đ°Đ¼Đ¼Đ° Đ½Đµ ÑƒĐºĐ°Đ·Đ°Đ½Đ° Process failed to start - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ·Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ Đ¿Ñ€Đ¾Ñ†ĐµÑÑ @@ -4479,7 +4450,7 @@ Please choose a different file name. Open - ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ @@ -4487,7 +4458,7 @@ Please choose a different file name. Check - + ĐÑ‚Đ¼ĐµÑ‚Đ¸Ñ‚ÑŒ @@ -4500,22 +4471,22 @@ Please choose a different file name. disabled feature used - иÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Đ»Đ¸ÑÑŒ Đ¾Ñ‚ĐºĐ»ÑÑ‡ĐµĐ½Đ½Ñ‹Đµ Đ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ÑÑ‚Đ¸ + иÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Đ½Đ¸Đµ Đ¾Ñ‚ĐºĐ»ÑÑ‡Ñ‘Đ½Đ½Ñ‹Ñ… Đ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ÑÑ‚ĐµĐ¹ bad char class syntax - bad char class syntax + Đ½ĐµĐ¿Ñ€Đ°Đ²Đ¸Đ»ÑŒĐ½Ñ‹Đ¹ ÑĐ¸Đ½Ñ‚Đ°ĐºÑĐ¸Ñ ĐºĐ»Đ°ÑÑĐ° ÑĐ¸Đ¼Đ²Đ¾Đ»Đ¾Đ² bad lookahead syntax - bad lookahead syntax + Đ½ĐµĐ¿Ñ€Đ°Đ²Đ¸Đ»ÑŒĐ½Ñ‹Đ¹ Đ¿Ñ€ĐµĐ´Đ²Đ°Ñ€Đ¸Ñ‚ĐµĐ»ÑŒĐ½Ñ‹Đ¹ ÑĐ¸Đ½Ñ‚Đ°ĐºÑĐ¸Ñ bad repetition syntax - bad repetition syntax + Đ½ĐµĐ¿Ñ€Đ°Đ²Đ¸Đ»ÑŒĐ½Ñ‹Đ¹ ÑĐ¸Đ½Ñ‚Đ°ĐºÑĐ¸Ñ Đ¿Đ¾Đ²Ñ‚Đ¾Ñ€ĐµĐ½Đ¸Ñ @@ -4543,22 +4514,22 @@ Please choose a different file name. Error to open database - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ±Đ°Đ·Ñƒ Đ´Đ°Đ½Đ½Ñ‹Ñ… Unable to begin transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ½Đ°Ñ‡Đ°Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to commit transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to rollback Transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºĐ°Ñ‚Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ @@ -4566,12 +4537,12 @@ Please choose a different file name. Unable to fetch results - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ Ñ€ĐµĐ·ÑƒĐ»ÑŒÑ‚Đ°Ñ‚ Unable to execute statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ @@ -4579,27 +4550,27 @@ Please choose a different file name. Error opening database - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ±Đ°Đ·Ñƒ Đ´Đ°Đ½Đ½Ñ‹Ñ… Error closing database - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ·Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ Đ±Đ°Đ·Ñƒ Đ´Đ°Đ½Đ½Ñ‹Ñ… Unable to begin transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ½Đ°Ñ‡Đ°Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to commit transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ Unable to rollback transaction - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºĐ°Ñ‚Đ¸Ñ‚ÑŒ Ñ‚Ñ€Đ°Đ½Đ·Đ°ĐºÑ†Đ¸Ñ @@ -4609,32 +4580,32 @@ Please choose a different file name. Unable to fetch row - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Ñ‚ÑŒ ÑÑ‚Ñ€Đ¾ĐºÑƒ Unable to execute statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ²Ñ‹Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to reset statement - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ±Ñ€Đ¾ÑĐ¸Ñ‚ÑŒ Đ²Ñ‹Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Unable to bind parameters - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¿Ñ€Đ¸Đ²ÑĐ·Đ°Ñ‚ÑŒ Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€ Parameter count mismatch - + ĐĐ¾Đ»Đ¸Ñ‡ĐµÑÑ‚Đ²Đ¾ Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Đ¾Đ² Đ½Đµ ÑĐ¾Đ²Đ¿Đ°Đ´Đ°ĐµÑ‚ No query - + ĐÑ‚ÑутÑÑ‚Đ²ÑƒĐµÑ‚ Đ·Đ°Đ¿Ñ€Đ¾Ñ @@ -4642,302 +4613,302 @@ Please choose a different file name. Scroll here - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ ÑÑĐ´Đ° Left edge - + Đ Đ»ĐµĐ²Đ¾Đ¹ Đ³Ñ€Đ°Đ½Đ¸Ñ†Đµ Top - + Đ’Đ²ĐµÑ€Ñ… Right edge - + Đ Đ¿Ñ€Đ°Đ²Đ¾Đ¹ Đ³Ñ€Đ°Đ½Đ¸Ñ†Đµ Bottom - + Đ’Đ½Đ¸Đ· Page left - + ĐĐ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Đ²Đ»ĐµĐ²Đ¾ Page up - + ĐĐ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Đ²Đ²ĐµÑ€Ñ… Page right - + ĐĐ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Đ²Đ¿Ñ€Đ°Đ²Đ¾ Page down - + ĐĐ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Đ²Đ½Đ¸Đ· Scroll left - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ»ĐµĐ²Đ¾ Scroll up - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ²ĐµÑ€Ñ… Scroll right - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ¿Ñ€Đ°Đ²Đ¾ Scroll down - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ½Đ¸Đ· Line up - Đ’Ñ‹Ñ€Đ¾Đ²Đ½ÑÑ‚ÑŒ + ĐĐ° ÑÑ‚Ñ€Đ¾ĐºÑƒ Đ²Đ²ĐµÑ€Ñ… Position - + ĐŸĐ¾Đ·Đ¸Ñ†Đ¸Ñ Line down - + ĐĐ° ÑÑ‚Ñ€Đ¾ĐºÑƒ Đ²Đ½Đ¸Đ· QSharedMemory - + %1: unable to set key on lock - + %1: Đ½ĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ уÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ ĐºĐ»Ñч Đ½Đ° Đ±Đ»Đ¾ĐºĐ¸Ñ€Đ¾Đ²ĐºÑƒ %1: create size is less then 0 - + %1: Ñ€Đ°Đ·Đ¼ĐµÑ€ Đ¼ĐµĐ½ÑŒÑˆĐµ Đ½ÑƒĐ»Ñ %1: unable to lock - + %1: Đ½ĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ·Đ°Đ±Đ»Đ¾ĐºĐ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ %1: unable to unlock - + %1: Đ½ĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Ñ€Đ°Đ·Đ±Đ»Đ¾ĐºĐ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ - + %1: permission denied - + %1: Đ´Đ¾ÑÑ‚ÑƒĐ¿ Đ·Đ°Đ¿Ñ€ĐµÑ‰Ñ‘Đ½ %1: already exists - + %1: ÑƒĐ¶Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚ %1: doesn't exists - + %1: Đ½Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚ %1: out of resources - + %1: Đ½ĐµĐ´Đ¾ÑÑ‚Đ°Ñ‚Đ¾Ñ‡Đ½Đ¾ Ñ€ĐµÑурÑĐ¾Đ² %1: unknown error %2 - + %1: Đ½ĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° %2 %1: key is empty - + %1: Đ¿ÑƒÑÑ‚Đ¾Đ¹ ĐºĐ»Ñч %1: unix key file doesn't exists - + %1: ÑĐ¿ĐµÑ†Đ¸Ñ„Đ¸Ñ‡ĐµÑĐºĐ¸Đ¹ ĐºĐ»Ñч unix Đ½Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚ %1: ftok failed - + %1: Đ¾ÑˆĐ¸Đ±ĐºĐ° ftok %1: unable to make key - + %1: Đ½ĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ ÑĐ¾Đ·Đ´Đ°Ñ‚ÑŒ ĐºĐ»Ñч %1: system-imposed size restrictions - + %1: ÑиÑÑ‚ĐµĐ¼Đ¾Đ¹ Đ½Đ°Đ»Đ¾Đ¶ĐµĐ½Ñ‹ Đ¾Đ³Ñ€Đ°Đ½Đ¸Ñ‡ĐµĐ½Đ¸Ñ Đ½Đ° Ñ€Đ°Đ·Đ¼ĐµÑ€ %1: not attached - + %1: Đ½Đµ Đ¿Ñ€Đ¸Đ»Đ¾Đ¶ĐµĐ½Đ½Ñ‹Đ¹ %1: invalid size - + %1: Đ½ĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ Ñ€Đ°Đ·Đ¼ĐµÑ€ %1: key error - + %1: Đ½ĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ ĐºĐ»Ñч %1: size query failed - + %1: Đ½Đµ ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ·Đ°Đ¿Ñ€Đ¾ÑĐ¸Ñ‚ÑŒ Ñ€Đ°Đ·Đ¼ĐµÑ€ QShortcut - + Space - Space + ĐŸÑ€Đ¾Đ±ĐµĐ» Esc - Esc + Tab - Tab + Backtab - Backtab + Backspace - Backspace + Return - Return + Enter - Enter + Ins - Ins + Del - Del + Pause - Pause + ĐŸĐ°ÑƒĐ·Đ° Print - Print + ĐŸĐµÑ‡Đ°Ñ‚Đ°Ñ‚ÑŒ SysReq - SysReq + Home - Home + End - End + Left - Left + Đ’Đ»ĐµĐ²Đ¾ Up - Up + Đ’Đ²ĐµÑ€Ñ… Right - Right + Đ’Đ¿Ñ€Đ°Đ²Đ¾ Down - Down + Đ’Đ½Đ¸Đ· PgUp - PgUp + PgDown - PgDown + CapsLock - CapsLock + NumLock - NumLock + ScrollLock - ScrollLock + @@ -4962,7 +4933,7 @@ Please choose a different file name. Stop - Đ¡Ñ‚Đ¾Đ¿ + ĐÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ @@ -4972,72 +4943,72 @@ Please choose a different file name. Volume Down - Đ¢Đ¸ÑˆĐµ + Volume Mute - Đ’Ñ‹ĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ Đ·Đ²ÑƒĐº + Volume Up - Đ“Ñ€Đ¾Đ¼Ñ‡Đµ + Bass Boost - Bass Boost + Bass Up - Bass Up + Bass Down - Bass Down + Treble Up - Treble Up + Treble Down - Treble Down + Media Play - Đ’Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Đµ + Media Stop - ĐÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Đµ + Media Previous - Đ’Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµÑÑ‚Đ¸ Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰ĐµĐµ + Media Next - Đ’Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµÑÑ‚Đ¸ ÑĐ»ĐµĐ´ÑƒÑÑ‰ĐµĐµ + Media Record - Đ—Đ°Đ¿Đ¸ÑÑŒ + Favorites - Đ˜Đ·Đ±Ñ€Đ°Đ½Đ½Đ¾Đµ + @@ -5047,102 +5018,102 @@ Please choose a different file name. Standby - Đ”ĐµĐ¶ÑƒÑ€Đ½Ñ‹Đ¹ Ñ€ĐµĐ¶Đ¸Đ¼ + Open URL - ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ URL + Launch Mail - ĐŸĐ¾Ñ‡Ñ‚Đ° + Launch Media - ĐŸÑ€Đ¾Đ¸Đ³Ñ€Ñ‹Đ²Đ°Ñ‚ĐµĐ»ÑŒ + Launch (0) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (0) + Launch (1) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (1) + Launch (2) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (2) + Launch (3) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (3) + Launch (4) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (4) + Launch (5) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (5) + Launch (6) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (6) + Launch (7) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (7) + Launch (8) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (8) + Launch (9) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (9) + Launch (A) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (A) + Launch (B) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (B) + Launch (C) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (C) + Launch (D) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (D) + Launch (E) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (E) + Launch (F) - Đ—Đ°Đ¿ÑƒÑÑ‚Đ¸Ñ‚ÑŒ (F) + @@ -5182,12 +5153,12 @@ Please choose a different file name. Insert - Đ’ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ + Đ’ÑÑ‚Đ°Đ²ĐºĐ° Delete - Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ + Đ£Đ´Đ°Đ»ĐµĐ½Đ¸Đµ @@ -5250,41 +5221,41 @@ Please choose a different file name. - - + + Ctrl - Ctrl + - - + + Shift - Shift + - - + + Alt - Alt + - - + + Meta - Meta + - + + - + + - + F%1 - F%1 + - + Home Page @@ -5294,27 +5265,27 @@ Please choose a different file name. Page left - + Đ¡Ñ‚Ñ€Đ°Đ½Đ¸Ñ†Đ° Đ²Đ»ĐµĐ²Đ¾ Page up - + Đ¡Ñ‚Ñ€Đ°Đ½Đ¸Ñ†Đ° Đ²Đ²ĐµÑ€Ñ… Position - + ĐŸĐ¾Đ·Đ¸Ñ†Đ¸Ñ Page right - + Đ¡Ñ‚Ñ€Đ°Đ½Đ¸Ñ†Đ° Đ²Đ¿Ñ€Đ°Đ²Đ¾ Page down - + Đ¡Ñ‚Ñ€Đ°Đ½Đ¸Ñ†Đ° Đ²Đ½Đ¸Đ· @@ -5322,72 +5293,72 @@ Please choose a different file name. Connection to proxy refused - + Đ’ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đ¸ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ¾Đ¼ Đ¾Ñ‚ĐºĐ°Đ·Đ°Đ½Đ¾ Connection to proxy closed prematurely - + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ¾Đ¼ Đ½ĐµĐ¾Đ¶Đ¸Đ´Đ°Đ½Đ½Đ¾ Đ·Đ°ĐºÑ€Ñ‹Ñ‚Đ¾ Proxy host not found - + ĐŸÑ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€ Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½ Connection to proxy timed out - + Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Ñ Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đ¾Đ¼ иÑÑ‚ĐµĐºĐ»Đ¾ Proxy authentication failed - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ¾Đ²Đ°Ñ‚ÑŒÑÑ Đ½Đ° Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đµ Proxy authentication failed: %1 - + Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ°Đ²Ñ‚Đ¾Ñ€Đ¸Đ·Đ¾Đ²Đ°Ñ‚ÑŒÑÑ Đ½Đ° Đ¿Ñ€Đ¾ĐºÑи-ÑĐµÑ€Đ²ĐµÑ€Đµ: %1 SOCKS version 5 protocol error - + ĐÑˆĐ¸Đ±ĐºĐ° Đ¿Ñ€Đ¾Ñ‚Đ¾ĐºĐ¾Đ»Đ° SOCKSv5 General SOCKSv5 server failure - + ĐÑˆĐ¸Đ±ĐºĐ° ÑĐµÑ€Đ²ĐµÑ€Đµ SOCKSv5 Connection not allowed by SOCKSv5 server - + Đ¡Đ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Đ½Đµ Ñ€Đ°Đ·Ñ€ĐµÑˆĐµĐ½Đ¾ ÑĐµÑ€Đ²ĐµÑ€Đ¾Đ¼ SOCKSv5 TTL expired - + TTL иÑÑ‚ĐµĐºĐ»Đ¾ SOCKSv5 command not supported - + ĐĐ¾Đ¼Đ°Đ½Đ´Đ° SOCKSv5 Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ Address type not supported - + Đ¢Đ¸Đ¿ Đ°Đ´Ñ€ĐµÑĐ° Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ Unknown SOCKSv5 proxy error code 0x%1 - + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° SOCKSv5 Đ¿Ñ€Đ¾ĐºÑи (ĐºĐ¾Đ´ 0x%1) Network operation timed out - + Đ’Ñ€ĐµĐ¼Ñ Đ½Đ° ÑĐµÑ‚ĐµĐ²ÑƒÑ Đ¾Đ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Đ¸ÑÑ‚ĐµĐºĐ»Đ¾ @@ -5395,12 +5366,12 @@ Please choose a different file name. More - + Đ‘Đ¾Đ»ÑŒÑˆĐµ Less - + ĐœĐµĐ½ÑŒÑˆĐµ @@ -5413,7 +5384,7 @@ Please choose a different file name. Delete this record? - Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ Ñту Đ·Đ°Đ¿Đ¸ÑÑŒ? + Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ Đ´Đ°Đ½Đ½ÑƒÑ Đ·Đ°Đ¿Đ¸ÑÑŒ? @@ -5452,7 +5423,7 @@ Please choose a different file name. Confirm - ĐŸĐ¾Đ´Ñ‚Đ²ĐµÑ€Đ´Đ¸Ñ‚ÑŒ + ĐŸĐ¾Đ´Ñ‚Đ²ĐµÑ€Đ¶Đ´ĐµĐ½Đ¸Đµ @@ -5465,12 +5436,12 @@ Please choose a different file name. Unable to write data: %1 - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ·Đ°Đ¿Đ¸ÑĐ°Ñ‚ÑŒ Đ´Đ°Đ½Đ½Ñ‹Đµ: %1 Error while reading: %1 - + ĐÑˆĐ¸Đ±ĐºĐ° Ñ‡Ñ‚ĐµĐ½Đ¸Ñ: %1 @@ -5490,12 +5461,12 @@ Please choose a different file name. Error creating SSL session, %1 - + ĐÑˆĐ¸Đ±ĐºĐ° ÑĐ¾Đ·Đ´Đ°Đ½Đ¸Ñ SSL-ÑеÑÑии, %1 Error creating SSL session: %1 - + ĐÑˆĐ¸Đ±ĐºĐ° ÑĐ¾Đ·Đ´Đ°Đ½Đ¸Ñ SSL-ÑеÑÑии: %1 @@ -5505,12 +5476,12 @@ Please choose a different file name. Error loading local certificate, %1 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ·Đ°Đ³Ñ€ÑƒĐ·ĐºĐ¸ Đ»Đ¾ĐºĐ°Đ»ÑŒĐ½Đ¾Đ³Đ¾ ÑĐµÑ€Ñ‚Đ¸Ñ„Đ¸ĐºĐ°Ñ‚Đ°, %1 Error loading private key, %1 - + ĐÑˆĐ¸Đ±ĐºĐ° Đ·Đ°Đ³Ñ€ÑƒĐ·ĐºĐ¸ Đ¿Ñ€Đ¸Đ²Đ°Ñ‚Đ½Đ¾Đ³Đ¾ ĐºĐ»ÑÑ‡Đ°, %1 @@ -5519,34 +5490,57 @@ Please choose a different file name. + QStateMachine + + + Missing initial state in compound state '%1' + + + + + Missing default state in history state '%1' + + + + + No common ancestor for targets and source of transition from state '%1' + + + + + Unknown error + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° + + + QSystemSemaphore %1: out of resources - + %1: Đ½ĐµĐ´Đ¾ÑÑ‚Đ°Ñ‚Đ¾Ñ‡Đ½Đ¾ Ñ€ĐµÑурÑĐ¾Đ² %1: permission denied - + %1: Đ´Đ¾ÑÑ‚ÑƒĐ¿ Đ·Đ°Đ¿Ñ€ĐµÑ‰Ñ‘Đ½ %1: already exists - + %1: ÑƒĐ¶Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚ %1: does not exist - + %1: Đ½Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚ %1: unknown error %2 - + %1: Đ½ĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ°Ñ Đ¾ÑˆĐ¸Đ±ĐºĐ° %2 @@ -5554,12 +5548,12 @@ Please choose a different file name. Unable to open connection - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚ĐºÑ€Ñ‹Ñ‚ÑŒ ÑĐ¾ĐµĐ´Đ¸Đ½ĐµĐ½Đ¸Đµ Unable to use database - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ иÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ÑŒ Đ±Đ°Đ·Ñƒ Đ´Đ°Đ½Đ½Ñ‹Ñ… @@ -5567,12 +5561,12 @@ Please choose a different file name. Scroll Left - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ»ĐµĐ²Đ¾ Scroll Right - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ¿Ñ€Đ°Đ²Đ¾ @@ -5580,7 +5574,7 @@ Please choose a different file name. Operation on socket is not supported - + ĐĐ¿ĐµÑ€Đ°Ñ†Đ¸Ñ Ñ ÑĐ¾ĐºĐµÑ‚Đ¾Đ¼ Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ÑÑ @@ -5588,42 +5582,42 @@ Please choose a different file name. &Undo - &ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ + &ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ &Redo - &ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ + &ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ Cu&t - &Đ’Ñ‹Ñ€ĐµĐ·Đ°Ñ‚ÑŒ + &Đ’Ñ‹Ñ€ĐµĐ·Đ°Ñ‚ÑŒ &Copy - &ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ + &ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Copy &Link Location - + Đ¡ĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ &Đ°Đ´Ñ€ĐµÑ ÑÑÑ‹Đ»ĐºĐ¸ &Paste - &Đ’ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ + Đ’&ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ Delete - Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ + Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ Select All - Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ²Ñе + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ²Ñе @@ -5632,13 +5626,13 @@ Please choose a different file name. Press - + ĐĐ°Đ¶Đ°Ñ‚ÑŒ Open - ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ @@ -5646,7 +5640,7 @@ Please choose a different file name. This platform does not support IPv6 - + Đ”Đ°Đ½Đ½Đ°Ñ Đ¿Đ»Đ°Ñ‚Ñ„Đ¾Ñ€Đ¼Đ° Đ½Đµ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ IPv6 @@ -5654,12 +5648,12 @@ Please choose a different file name. Undo - ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ + ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ Redo - ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ + ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ @@ -5667,7 +5661,7 @@ Please choose a different file name. <empty> - + <Đ¿ÑƒÑÑ‚Đ¾> @@ -5675,12 +5669,12 @@ Please choose a different file name. Undo - ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ + ĐÑ‚Đ¼ĐµĐ½Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ Redo - ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ + ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€Đ¸Ñ‚ÑŒ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ @@ -5746,160 +5740,160 @@ Please choose a different file name. Request cancelled - + Đ—Đ°Đ¿Ñ€Đ¾Ñ Đ¾Ñ‚Đ¼ĐµĐ½Ñ‘Đ½ Request blocked - + Đ—Đ°Đ¿Ñ€Đ¾Ñ Đ±Đ»Đ¾ĐºĐ¸Ñ€Đ¾Đ²Đ°Đ½ Cannot show URL - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚Đ¾Đ±Ñ€Đ°Đ·Đ¸Ñ‚ÑŒ URL Frame load interruped by policy change - + Đ—Đ°Đ³Ñ€ÑƒĐ·ĐºĐ° Ñ„Ñ€ÑĐ¹Đ¼Đ° Đ¿Ñ€ĐµÑ€Đ²Đ°Đ½Đ° Đ¸Đ·Đ¼ĐµĐ½ĐµĐ½Đ¸ĐµĐ¼ Đ¿Đ¾Đ»Đ¸Ñ‚Đ¸ĐºĐ¸ Cannot show mimetype - + ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ¾Ñ‚Đ¾Đ±Ñ€Đ°Đ·Đ¸Ñ‚ÑŒ Ñ‚Đ¸Đ¿ MIME File does not exist - + Đ¤Đ°Đ¹Đ» Đ½Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚ QWebPage - + Bad HTTP request - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ HTTP-Đ·Đ°Đ¿Ñ€Đ¾Ñ Submit default label for Submit buttons in forms on web pages - + ĐÑ‚Đ¿Ñ€Đ°Đ²Đ¸Ñ‚ÑŒ Submit Submit (input element) alt text for <input> elements with no alt, title, or value - + ĐÑ‚Đ¿Ñ€Đ°Đ²Đ¸Ñ‚ÑŒ Reset default label for Reset buttons in forms on web pages - + Đ¡Đ±Ñ€Đ¾ÑĐ¸Ñ‚ÑŒ This is a searchable index. Enter search keywords: text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' - + Đ˜Đ½Đ´ĐµĐºÑ Đ¿Đ¾Đ¸ÑĐºĐ°. Đ’Đ²ĐµĐ´Đ¸Ñ‚Đµ ĐºĐ»ÑÑ‡ĐµĐ²Ñ‹Đµ ÑĐ»Đ¾Đ²Đ° Đ´Đ»Ñ Đ¿Đ¾Đ¸ÑĐºĐ°: Choose File title for file button used in HTML forms - + ĐĐ±Đ·Đ¾Ñ€... No file selected text to display in file button used in HTML forms when no file is selected - + Đ¤Đ°Đ¹Đ» Đ½Đµ ÑƒĐºĐ°Đ·Đ°Đ½ Open in New Window Open in New Window context menu item - + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ² Đ½Đ¾Đ²Đ¾Đ¼ Đ¾ĐºĐ½Đµ Save Link... Download Linked File context menu item - + Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ Đ¿Đ¾ ÑÑÑ‹Đ»ĐºĐµ ĐºĐ°Đº... Copy Link Copy Link context menu item - + ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Đ°Đ´Ñ€ĐµÑ ÑÑÑ‹Đ»ĐºĐ¸ Open Image Open Image in New Window context menu item - + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ¸Đ·Đ¾Đ±Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Save Image Download Image context menu item - + Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ Đ¸Đ·Đ¾Đ±Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Copy Image Copy Link context menu item - + ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Đ¸Đ·Đ¾Đ±Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ Đ² Đ±ÑƒÑ„Ñ„ĐµÑ€ Đ¾Đ±Đ¼ĐµĐ½Đ° Open Frame Open Frame in New Window context menu item - + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Ñ„Ñ€ÑĐ¹Đ¼ Copy Copy context menu item - + ĐĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Go Back Back context menu item - + ĐĐ°Đ·Đ°Đ´ Go Forward Forward context menu item - + Đ’Đ¿ĐµÑ€ĐµĐ´ Stop Stop context menu item - Đ¡Ñ‚Đ¾Đ¿ + ĐÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Reload Reload context menu item - + ĐĐ±Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Cut Cut context menu item - + Đ’Ñ‹Ñ€ĐµĐ·Đ°Ñ‚ÑŒ Paste Paste context menu item - + Đ’ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ @@ -5911,7 +5905,7 @@ Please choose a different file name. Ignore Ignore Spelling context menu item - + Đ˜Đ³Đ½Đ¾Ñ€Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ @@ -5935,13 +5929,13 @@ Please choose a different file name. Open Link Open Link context menu item - + ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ ÑÑÑ‹Đ»ĐºÑƒ Ignore Ignore Grammar context menu item - + Đ˜Đ³Đ½Đ¾Ñ€Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ @@ -5983,97 +5977,97 @@ Please choose a different file name. Fonts Font context sub-menu item - + Đ¨Ñ€Đ¸Ñ„Ñ‚Ñ‹ Bold Bold context menu item - + Đ–Đ¸Ñ€Đ½Ñ‹Đ¹ Italic Italic context menu item - + ĐурÑĐ¸Đ² Underline Underline context menu item - + ĐŸĐ¾Đ´Ñ‡Ñ‘Ñ€ĐºĐ½ÑƒÑ‚Ñ‹Đ¹ Outline Outline context menu item - + ĐŸĐµÑ€ĐµÑ‡Ñ‘Ñ€ĐºĐ½ÑƒÑ‚Ñ‹Đ¹ Direction Writing direction context sub-menu item - + ĐĐ°Đ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Đµ Text Direction Text direction context sub-menu item - + ĐĐ°Đ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Đµ Ñ‚ĐµĐºÑÑ‚Đ° Default Default writing direction context menu item - + ĐŸĐ¾ ÑƒĐ¼Đ¾Đ»Ñ‡Đ°Đ½Đ¸Ñ LTR Left to Right context menu item - + Đ¡Đ»ĐµĐ²Đ° Đ½Đ°Đ¿Ñ€Đ°Đ²Đ¾ RTL Right to Left context menu item - + Đ¡Đ¿Ñ€Đ°Đ²Đ° Đ½Đ°Đ»ĐµĐ²Đ¾ Inspect Inspect Element context menu item - + ĐŸÑ€Đ¾Đ²ĐµÑ€Đ¸Ñ‚ÑŒ No recent searches Label for only item in menu that appears when clicking on the search field image, when no searches have been performed - + Đ˜ÑÑ‚Đ¾Ñ€Đ¸Ñ Đ¿Đ¾Đ¸ÑĐºĐ° Đ¿ÑƒÑÑ‚Đ° Recent searches label for first item in the menu that appears when clicking on the search field image, used as embedded menu title - + Đ˜ÑÑ‚Đ¾Ñ€Đ¸Ñ Đ¿Đ¾Đ¸ÑĐºĐ° Clear recent searches menu item in Recent Searches menu that empties menu's contents - + ĐÑ‡Đ¸ÑÑ‚Đ¸Ñ‚ÑŒ иÑÑ‚Đ¾Ñ€Đ¸Ñ Đ¿Đ¾Đ¸ÑĐºĐ° Unknown Unknown filesize FTP directory listing item - + ĐĐµĐ¸Đ·Đ²ĐµÑÑ‚Đ½Đ¾ %1 (%2x%3 pixels) Title string for images - + %1 (%2x%3 px) @@ -6083,74 +6077,76 @@ Please choose a different file name. Scroll here - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ ÑÑĐ´Đ° Left edge - + Đ Đ»ĐµĐ²Đ¾Đ¹ Đ³Ñ€Đ°Đ½Đ¸Ñ†Đµ Top - + Đ’Đ²ĐµÑ€Ñ… Right edge - + Đ Đ¿Ñ€Đ°Đ²Đ¾Đ¹ Đ³Ñ€Đ°Đ½Đ¸Ñ†Đµ Bottom - + Đ’Đ½Đ¸Đ· Page left - + ĐĐ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Đ²Đ»ĐµĐ²Đ¾ Page up - + ĐĐ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Đ²Đ²ĐµÑ€Ñ… Page right - + ĐĐ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Đ²Đ¿Ñ€Đ°Đ²Đ¾ Page down - + ĐĐ° ÑÑ‚Ñ€Đ°Đ½Đ¸Ñ†Ñƒ Đ²Đ½Đ¸Đ· Scroll left - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ»ĐµĐ²Đ¾ Scroll up - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ²ĐµÑ€Ñ… Scroll right - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ¿Ñ€Đ°Đ²Đ¾ Scroll down - + ĐŸÑ€Đ¾ĐºÑ€ÑƒÑ‚Đ¸Ñ‚ÑŒ Đ²Đ½Đ¸Đ· %n file(s) number of chosen file - - + + %n Ñ„Đ°Đ¹Đ»(Đ°) + %n Ñ„Đ°Đ¹Đ»Đ° + %n Ñ„Đ°Đ¹Đ»Đ¾Đ² @@ -6169,149 +6165,149 @@ Please choose a different file name. - + Move the cursor to the next character - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đº ÑĐ»ĐµĐ´ÑƒÑÑ‰ĐµĐ¼Ñƒ ÑĐ¸Đ¼Đ²Đ¾Đ»Ñƒ Move the cursor to the previous character - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đº Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰ĐµĐ¼Ñƒ ÑĐ¸Đ¼Đ²Đ¾Đ»Ñƒ Move the cursor to the next word - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đº ÑĐ»ĐµĐ´ÑƒÑÑ‰ĐµĐ¼Ñƒ ÑĐ»Đ¾Đ²Ñƒ Move the cursor to the previous word - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đº Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰ĐµĐ¼Ñƒ ÑĐ»Đ¾Đ²Ñƒ Move the cursor to the next line - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đ½Đ° ÑĐ»ĐµĐ´ÑƒÑÑ‰ÑƒÑ ÑÑ‚Ñ€Đ¾ĐºÑƒ Move the cursor to the previous line - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đ½Đ° Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰ÑƒÑ ÑÑ‚Ñ€Đ¾ĐºÑƒ Move the cursor to the start of the line - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đ² Đ½Đ°Ñ‡Đ°Đ»Đ¾ ÑÑ‚Ñ€Đ¾ĐºĐ¸ Move the cursor to the end of the line - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đ² ĐºĐ¾Đ½ĐµÑ† ÑÑ‚Ñ€Đ¾ĐºĐ¸ Move the cursor to the start of the block - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đ² Đ½Đ°Ñ‡Đ°Đ»Đ¾ Đ±Đ»Đ¾ĐºĐ° Move the cursor to the end of the block - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đ² ĐºĐ¾Đ½ĐµÑ† Đ±Đ»Đ¾ĐºĐ° Move the cursor to the start of the document - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đ² Đ½Đ°Ñ‡Đ°Đ»Đ¾ Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ° Move the cursor to the end of the document - + ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ ÑƒĐºĐ°Đ·Đ°Ñ‚ĐµĐ»ÑŒ Đ² ĐºĐ¾Đ½ĐµÑ† Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ° Select all - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ²ÑÑ‘ Select to the next character - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ ÑĐ»ĐµĐ´ÑƒÑÑ‰ĐµĐ³Đ¾ ÑĐ¸Đ¼Đ²Đ¾Đ»Đ° Select to the previous character - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰ĐµĐ³Đ¾ ÑĐ¸Đ¼Đ²Đ¾Đ»Đ° Select to the next word - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ ÑĐ»ĐµĐ´ÑƒÑÑ‰ĐµĐ³Đ¾ ÑĐ»Đ¾Đ²Đ° Select to the previous word - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰ĐµĐ³Đ¾ ÑĐ»Đ¾Đ²Đ° Select to the next line - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ ÑĐ»ĐµĐ´ÑƒÑÑ‰ĐµĐ¹ ÑÑ‚Ñ€Đ¾ĐºĐ¸ Select to the previous line - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰ĐµĐ¹ ÑÑ‚Ñ€Đ¾ĐºĐ¸ Select to the start of the line - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ Đ½Đ°Ñ‡Đ°Đ»Đ° ÑÑ‚Ñ€Đ¾ĐºĐ¸ Select to the end of the line - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ ĐºĐ¾Đ½Ñ†Đ° ÑÑ‚Ñ€Đ¾ĐºĐ¸ Select to the start of the block - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ Đ½Đ°Ñ‡Đ°Đ»Đ° Đ±Đ»Đ¾ĐºĐ° Select to the end of the block - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ ĐºĐ¾Đ½Ñ†Đ° Đ±Đ»Đ¾ĐºĐ° Select to the start of the document - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ Đ½Đ°Ñ‡Đ°Đ»Đ° Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ° Select to the end of the document - + Đ’Ñ‹Đ´ĐµĐ»Đ¸Ñ‚ÑŒ Đ´Đ¾ ĐºĐ¾Đ½Ñ†Đ° Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ° Delete to the start of the word - + Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ Đ´Đ¾ Đ½Đ°Ñ‡Đ°Đ»Đ° ÑĐ»Đ¾Đ²Đ° Delete to the end of the word - + Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ Đ´Đ¾ ĐºĐ¾Đ½Ñ†Đ° ÑĐ»Đ¾Đ²Đ° Insert a new paragraph - + Đ’ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ Đ½Đ¾Đ²Ñ‹Đ¹ Đ¿Đ°Ñ€Đ°Đ³Ñ€Đ°Ñ„ Insert a new line - + Đ’ÑÑ‚Đ°Đ²Đ¸Ñ‚ÑŒ Đ½Đ¾Đ²ÑƒÑ ÑÑ‚Ñ€Đ¾ĐºÑƒ @@ -6319,77 +6315,73 @@ Please choose a different file name. What's This? - Đ§Ñ‚Đ¾ ÑÑ‚Đ¾? + Đ§Ñ‚Đ¾ ÑÑ‚Đ¾? QWidget - + * - + * QWizard - < &Back - < &ĐĐ°Đ·Đ°Đ´ - - - - &Finish - &Đ¤Đ¸Đ½Đ¸Ñˆ - - - - &Help - &Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° - - - Go Back - + ĐĐ°Đ·Đ°Đ´ Continue - + ĐŸÑ€Đ¾Đ´Đ¾Đ»Đ¶Đ¸Ñ‚ÑŒ Commit - + ĐÑ‚Đ¿Ñ€Đ°Đ²Đ¸Ñ‚ÑŒ Done - - - - Quit - Đ’Ñ‹Ñ…Đ¾Đ´ + Đ“Đ¾Ñ‚Đ¾Đ²Đ¾ Help - Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° + Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° - + + < &Back + < &ĐĐ°Đ·Đ°Đ´ + + + + &Finish + &Đ—Đ°ĐºĐ¾Đ½Ñ‡Đ¸Ñ‚ÑŒ + + + Cancel - ĐÑ‚Đ¼ĐµĐ½Đ° + ĐÑ‚Đ¼ĐµĐ½Đ° + + + + &Help + &Đ¡Đ¿Ñ€Đ°Đ²ĐºĐ° - + &Next - + &Đ’Đ¿ĐµÑ€ĐµĐ´ &Next > - &Đ’Đ¿ĐµÑ€ĐµĐ´ > + &Đ’Đ¿ĐµÑ€ĐµĐ´ > @@ -6397,43 +6389,43 @@ Please choose a different file name. &Restore - &Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ + &Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ &Move - &ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ + &ĐŸĐµÑ€ĐµĐ¼ĐµÑÑ‚Đ¸Ñ‚ÑŒ &Size - &Đ Đ°Đ·Đ¼ĐµÑ€ + &Đ Đ°Đ·Đ¼ĐµÑ€ Mi&nimize - &Đ¡Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ + &ĐœĐ¸Đ½Đ¸Đ¼Đ¸Đ·Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Ma&ximize - Đ &Đ°Đ·Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ + Đ &Đ°ÑĐ¿Đ°Ñ…Đ½ÑƒÑ‚ÑŒ &Close - &Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + &Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ Stay on &Top - Đ’ÑĐµĐ³Đ´Đ° &Đ½Đ°Đ²ĐµÑ€Ñ…Ñƒ + ĐÑÑ‚Đ°Đ²Đ°Ñ‚ÑŒÑÑ &ÑĐ²ĐµÑ€Ñ…Ñƒ Sh&ade - Đ¡Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ Đ² Đ·Đ°&Đ³Đ¾Đ»Đ¾Đ²Đ¾Đº + Đ¡Đ²&ĐµÑ€Đ½ÑƒÑ‚ÑŒ Đ² Đ·Đ°Đ³Đ¾Đ»Đ¾Đ²Đ¾Đº @@ -6444,22 +6436,22 @@ Please choose a different file name. Minimize - Đ¡Đ²ĐµÑ€Đ½ÑƒÑ‚ÑŒ + ĐœĐ¸Đ½Đ¸Đ¼Đ¸Đ·Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Restore Down - Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ + Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Close - Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ + Đ—Đ°ĐºÑ€Ñ‹Ñ‚ÑŒ &Unshade - Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ из Đ·Đ°&Đ³Đ¾Đ»Đ¾Đ²ĐºĐ° + Đ’&Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ из Đ·Đ°Đ³Đ¾Đ»Đ¾Đ²ĐºĐ° @@ -6472,7 +6464,7 @@ Please choose a different file name. error triggered by consumer - Đ¾ÑˆĐ¸Đ±ĐºĐ° Đ¸Đ½Đ¸Ñ†Đ¸Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ° Đ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ĐµĐ»ĐµĐ¼ + Đ¾ÑˆĐ¸Đ±ĐºĐ° Đ²Ñ‹Đ·Đ²Đ°Đ½Đ° Đ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Ñ‚ĐµĐ»ĐµĐ¼ @@ -6482,22 +6474,22 @@ Please choose a different file name. more than one document type definition - Đ¾Đ¿Ñ€ĐµĐ´ĐµĐ»ĐµĐ½ Đ±Đ¾Đ»ĐµĐµ, Ñ‡ĐµĐ¼ Đ¾Đ´Đ¸Đ½ Ñ‚Đ¸Đ¿ Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ¾Đ² + ÑƒĐºĐ°Đ·Đ°Đ½Đ¾ Đ±Đ¾Đ»ĐµĐµ Đ¾Đ´Đ½Đ¾Đ³Đ¾ Ñ‚Đ¸Đ¿Đ° Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ° error occurred while parsing element - Đ² Đ¿Ñ€Đ¾Ñ†ĐµÑÑе Đ³Ñ€Đ°Đ¼Đ¼Đ°Ñ‚Đ¸Ñ‡ĐµÑĐºĐ¾Đ³Đ¾ Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° ÑĐ»ĐµĐ¼ĐµĐ½Ñ‚Đ° Đ¿Ñ€Đ¾Đ¸Đ·Đ¾ÑˆĐ»Đ° Đ¾ÑˆĐ¸Đ±ĐºĐ° + Đ¾ÑˆĐ¸Đ±ĐºĐ° Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° ÑĐ»ĐµĐ¼ĐµĐ½Ñ‚Đ° tag mismatch - Đ¾Ñ‚ÑутÑÑ‚Đ²ÑƒĐµÑ‚ Ñ‚ĐµĐ³ + Ñ‚ÑĐ³ Đ½Đµ ÑĐ¾Đ²Đ¿Đ°Đ´Đ°ĐµÑ‚ error occurred while parsing content - Đ² Đ¿Ñ€Đ¾Ñ†ĐµÑÑе Đ³Ñ€Đ°Đ¼Đ¼Đ°Ñ‚Đ¸Ñ‡ĐµÑĐºĐ¾Đ³Đ¾ Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° Đ¿Ñ€Đ¾Đ¸Đ·Đ¾ÑˆĐ»Đ° Đ¾ÑˆĐ¸Đ±ĐºĐ° + Đ¾ÑˆĐ¸Đ±ĐºĐ° Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ° @@ -6507,101 +6499,101 @@ Please choose a different file name. invalid name for processing instruction - Đ½ĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ Đ¸Đ¼Ñ Đ´Đ¸Ñ€ĐµĐºÑ‚Đ¸Đ²Ñ‹ + Đ½ĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ Đ¸Đ¼Ñ Đ´Đ¸Ñ€ĐµĐºÑ‚Đ¸Đ²Ñ‹ Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° version expected while reading the XML declaration - Đ¿Ñ€Đ¸ Ñ‡Ñ‚ĐµĐ½Đ¸Đ¸ XML-Ñ‚ĐµĐ³Đ° Đ¾Đ¶Đ¸Đ´Đ°Đ»ÑÑ Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€ version + Đ² Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Đ¸ XML Đ¾Đ¶Đ¸Đ´Đ°ĐµÑ‚ÑÑ Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Đµ Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Đ° version wrong value for standalone declaration - Đ½ĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Đ° standalone + Đ½ĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Ñ standalone encoding declaration or standalone declaration expected while reading the XML declaration - Đ¿Ñ€Đ¸ Ñ‡Ñ‚ĐµĐ½Đ¸Đ¸ XML-Ñ‚ĐµĐ³Đ° Đ¾Đ¶Đ¸Đ´Đ°Đ»ÑÑ Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€ encoding или Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€ standalone + Đ² Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Đ¸ XML Đ¾Đ¶Đ¸Đ´Đ°ĐµÑ‚ÑÑ Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Đµ Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Đ° encoding или standalone standalone declaration expected while reading the XML declaration - Đ¿Ñ€Đ¸ Ñ‡Ñ‚ĐµĐ½Đ¸Đ¸ XML-Ñ‚ĐµĐ³Đ° Đ¾Đ¶Đ¸Đ´Đ°Đ»ÑÑ Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€ standalone + Đ² Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Đ¸ XML Đ¾Đ¶Đ¸Đ´Đ°ĐµÑ‚ÑÑ Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Đµ Đ¿Đ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Đ° standalone error occurred while parsing document type definition - Đ² Đ¿Ñ€Đ¾Ñ†ĐµÑÑе Đ³Ñ€Đ°Đ¼Đ¼Đ°Ñ‚Đ¸Ñ‡ĐµÑĐºĐ¾Đ³Đ¾ Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° Ñ‚Đ¸Đ¿Đ° Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ° Đ¿Ñ€Đ¾Đ¸Đ·Đ¾ÑˆĐ»Đ° Đ¾ÑˆĐ¸Đ±ĐºĐ° + Đ¾ÑˆĐ¸Đ±ĐºĐ° Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Ñ Ñ‚Đ¸Đ¿Đ° Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ° letter is expected - Đ¾Đ¶Đ¸Đ´Đ°Đ»ÑÑ ÑĐ¸Đ¼Đ²Đ¾Đ» + Đ¾Đ¶Đ¸Đ´Đ°Đ»Đ°ÑÑŒ Đ±ÑƒĐºĐ²Đ° error occurred while parsing comment - Đ² Đ¿Ñ€Đ¾Ñ†ĐµÑÑе Đ³Ñ€Đ°Đ¼Đ¼Đ°Ñ‚Đ¸Ñ‡ĐµÑĐºĐ¾Đ³Đ¾ Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° ĐºĐ¾Đ¼Đ¼ĐµĐ½Ñ‚Đ°Ñ€Đ¸Ñ Đ¿Ñ€Đ¾Đ¸Đ·Đ¾ÑˆĐ»Đ° Đ¾ÑˆĐ¸Đ±ĐºĐ° + Đ¾ÑˆĐ¸Đ±ĐºĐ° Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° ĐºĐ¾Đ¼Đ¼ĐµĐ½Ñ‚Đ°Ñ€Đ¸Ñ error occurred while parsing reference - Đ² Đ¿Ñ€Đ¾Ñ†ĐµÑÑе Đ³Ñ€Đ°Đ¼Đ¼Đ°Ñ‚Đ¸Ñ‡ĐµÑĐºĐ¾Đ³Đ¾ Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° ÑÑÑ‹Đ»ĐºĐ¸ Đ¿Ñ€Đ¾Đ¸Đ·Đ¾ÑˆĐ»Đ° Đ¾ÑˆĐ¸Đ±ĐºĐ° + Đ¾ÑˆĐ¸Đ±ĐºĐ° Ñ€Đ°Đ·Đ±Đ¾Ñ€Đ° ÑÑÑ‹Đ»ĐºĐ¸ internal general entity reference not allowed in DTD - internal general entity reference not allowed in DTD + Đ²Đ½ÑƒÑ‚Ñ€ĐµĐ½Đ½ÑÑ ÑÑÑ‹Đ»ĐºĐ° Đ½Đ° Đ¾Đ±Ñ‰Đ¸Đ¹ Đ¾Đ±ÑĐºÑ‚ Đ½ĐµĐ´Đ¾Đ¿ÑƒÑÑ‚Đ¸Đ¼Đ° Đ² DTD external parsed general entity reference not allowed in attribute value - external parsed general entity reference not allowed in attribute value + Đ²Đ½ĐµÑˆĐ½ÑÑ ÑÑÑ‹Đ»ĐºĐ° Đ½Đ° Đ¾Đ±Ñ‰Đ¸Đ¹ Đ¾Đ±ÑĐµĐºÑ‚ Đ½ĐµĐ´Đ¾Đ¿ÑƒÑÑ‚Đ¸Đ¼Đ° Đ² Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Đ¸ Đ°Ñ‚Ñ€Đ¸Đ±ÑƒÑ‚Đ° external parsed general entity reference not allowed in DTD - external parsed general entity reference not allowed in DTD + Đ²Đ½ĐµÑˆĐ½ÑÑ ÑÑÑ‹Đ»ĐºĐ° Đ½Đ° Đ¾Đ±Ñ‰Đ¸Đ¹ Đ¾Đ±ÑĐµĐºÑ‚ Đ½ĐµĐ´Đ¾Đ¿ÑƒÑÑ‚Đ¸Đ¼Đ° Đ² DTD unparsed entity reference in wrong context - unparsed entity reference in wrong context + Đ½ĐµÑ€Đ°Đ·Đ¾Đ±Ñ€Đ°Đ½Đ½Đ°Ñ ÑÑÑ‹Đ»ĐºĐ° Đ½Đ° Đ¾Đ±ÑĐµĐºÑ‚ Đ² Đ½ĐµĐ¿Ñ€Đ°Đ²Đ¸Đ»ÑŒĐ½Đ¾Đ¼ ĐºĐ¾Đ½Ñ‚ĐµĐºÑÑ‚Đµ recursive entities - Ñ€ĐµĐºÑƒÑ€ÑĐ¸Đ²Đ½Ñ‹Đµ Đ¾Đ±ÑĐµĐºÑ‚Ñ‹ + Ñ€ĐµĐºÑƒÑ€ÑĐ¸Ñ Đ¾Đ±ÑĐµĐºÑ‚Đ¾Đ² error in the text declaration of an external entity - error in the text declaration of an external entity + Đ¾ÑˆĐ¸Đ±ĐºĐ° Đ² Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Đ¸ Đ²Đ½ĐµÑˆĐ½ĐµĐ³Đ¾ Đ¾Đ±ÑĐµĐºÑ‚Đ° QXmlStream - + Extra content at end of document. Invalid entity value. - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ Đ¾Đ±ÑĐµĐºÑ‚Đ°. Invalid XML character. - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ ÑĐ¸Đ¼Đ²Đ¾Đ» XML. Sequence ']]>' not allowed in content. - + ĐŸĐ¾ÑĐ»ĐµĐ´Đ¾Đ²Đ°Ñ‚ĐµĐ»ÑŒĐ½Đ¾ÑÑ‚ÑŒ ']]>' Đ½Đµ Đ´Đ¾Đ¿ÑƒÑĐºĐ°ĐµÑ‚ÑÑ Đ² ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đ¼. @@ -6626,7 +6618,7 @@ Please choose a different file name. Unsupported XML version. - + ĐĐµĐ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµĐ¼Đ°Ñ Đ²ĐµÑ€ÑĐ¸Ñ XML. @@ -6641,37 +6633,37 @@ Please choose a different file name. Standalone accepts only yes or no. - + ĐŸÑĐµĐ²Đ´Đ¾Đ°Ñ‚Ñ€Đ¸Đ±ÑƒÑ‚ 'standalone' Đ¼Đ¾Đ¶ĐµÑ‚ Đ¿Ñ€Đ¸Đ½Đ¸Đ¼Đ°Ñ‚ÑŒ Ñ‚Đ¾Đ»ÑŒĐºĐ¾ Đ·Đ½Đ°Ñ‡ĐµĐ½Đ¸Đµ yes или no. Invalid attribute in XML declaration. - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ Đ°Ñ‚Ñ€Đ¸Đ±ÑƒÑ‚ Đ² Đ¾Đ±ÑÑĐ²Đ»ĐµĐ½Đ¸Đ¸ XML. Premature end of document. - + ĐĐµĐ¾Đ¶Đ¸Đ´Đ°Đ½Đ½Ñ‹Đ¹ ĐºĐ¾Đ½ĐµÑ† Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚Đ°. Invalid document. - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Ñ‹Đ¹ Đ´Đ¾ĐºÑƒĐ¼ĐµĐ½Ñ‚. Expected - + ĐĐ¶Đ¸Đ´Đ°Đ»Đ¾ÑÑŒ , but got ' - + , Đ¿Đ¾Đ»ÑƒÑ‡Đ¸Đ»Đ¸ ' Unexpected ' - + ĐĐµĐ¾Đ¶Đ¸Đ´Đ°Đ½Đ½Đ¾Đµ ' @@ -6686,7 +6678,7 @@ Please choose a different file name. Start tag expected. - + ĐĐ¶Đ¸Đ´Đ°ĐµÑ‚ÑÑ Đ½Đ°Ñ‡Đ°Đ»Đ¾ Ñ‚ÑĐ³Đ°. @@ -6719,12 +6711,12 @@ Please choose a different file name. Invalid XML name. - + ĐĐµĐºĐ¾Ñ€Ñ€ĐµĐºÑ‚Đ½Đ¾Đµ Đ¸Đ¼Ñ XML. Opening and ending tag mismatch. - + ĐÑ‚ĐºÑ€Ñ‹Đ²Đ°ÑÑ‰Đ¸Đ¹ Ñ‚ÑĐ³ Đ½Đµ ÑĐ¾Đ²Đ¿Đ°Đ´Đ°ĐµÑ‚ Ñ Đ·Đ°ĐºÑ€Ñ‹Đ²Đ°ÑÑ‰Đ¸Đ¼. @@ -6757,7 +6749,7 @@ Please choose a different file name. The standalone pseudo attribute must appear after the encoding. - + ĐŸÑĐµĐ²Đ´Đ¾Đ°Ñ‚Ñ€Đ¸Đ±ÑƒÑ‚ 'standalone' Đ´Đ¾Đ»Đ¶ĐµĐ½ Đ½Đ°Ñ…Đ¾Đ´Đ¸Ñ‚ÑŒÑÑ Đ¿Đ¾Ñле ÑƒĐºĐ°Đ·Đ°Đ½Đ¸Ñ ĐºĐ¾Đ´Đ¸Ñ€Đ¾Đ²ĐºĐ¸. @@ -6788,11 +6780,6 @@ Please choose a different file name. - - Attribute %1 can't be serialized because it appears at the top level. - - - Year %1 is invalid because it begins with %2. @@ -7070,6 +7057,8 @@ Please choose a different file name. %1 takes at most %n argument(s). %2 is therefore invalid. + + @@ -7077,6 +7066,8 @@ Please choose a different file name. %1 requires at least %n argument(s). %2 is therefore invalid. + + @@ -7165,7 +7156,7 @@ Please choose a different file name. - + It will not be possible to retrieve %1. @@ -7568,6 +7559,11 @@ Please choose a different file name. + + Attribute %1 can't be serialized because it appears at the top level. + + + %1 is an unsupported encoding. @@ -7809,13 +7805,13 @@ Please choose a different file name. Muted - + Без Đ·Đ²ÑƒĐºĐ° Volume: %1% - + Đ“Ñ€Đ¾Đ¼ĐºĐ¾ÑÑ‚ÑŒ: %1% -- cgit v0.12 From c95384106fc69c2e78db20a10e8bedc14f3c58d5 Mon Sep 17 00:00:00 2001 From: axasia Date: Sun, 24 May 2009 17:11:13 +0900 Subject: Update japanese translation of Qt Linguist. --- translations/linguist_ja.qm | Bin 30494 -> 36145 bytes translations/linguist_ja.ts | 466 ++++++++++++++++++++++---------------------- 2 files changed, 237 insertions(+), 229 deletions(-) diff --git a/translations/linguist_ja.qm b/translations/linguist_ja.qm index cdb7c1c..a377318 100644 Binary files a/translations/linguist_ja.qm and b/translations/linguist_ja.qm differ diff --git a/translations/linguist_ja.ts b/translations/linguist_ja.ts index 7af3ebb..685af88 100644 --- a/translations/linguist_ja.ts +++ b/translations/linguist_ja.ts @@ -6,7 +6,7 @@ (New Entry) - + (æ–°ă—ă„é …ç›®) @@ -48,74 +48,74 @@ Batch Translation of '%1' - Qt Linguist - + '%1' ă®ä¸€æ‹¬ç¿»è¨³ - Qt Linguist Batch translated %n entries - - + + %n é …ç›®ăŒä¸€æ‹¬ç¿»è¨³ă•ă‚Œă¾ă—ăŸ Qt Linguist - Batch Translation - Qt Linguist - 一括翻訳 + Qt Linguist - 一括翻訳 Options - ă‚ªăƒ—ă‚·ăƒ§ăƒ³ + ă‚ªăƒ—ă‚·ăƒ§ăƒ³ Set translated entries to finished - 翻訳ă•ă‚ŒăŸé …ç›®ă‚’å®Œäº†ă«ă™ă‚‹ + 翻訳ă•ă‚ŒăŸé …ç›®ă‚’å®Œäº†ă«ă™ă‚‹ Retranslate entries with existing translation - + 訳èªăŒă‚る項目をå†åº¦ç¿»è¨³ă™ă‚‹ Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked. - + 注æ„:'翻訳ă•ă‚ŒăŸé …ç›®ă‚’å®Œäº†ă«ă™ă‚‹'ă«ăƒă‚§ăƒƒă‚¯ăŒă¤ă„ă¦ă„ăªă„å ´åˆă€ç¿»è¨³ă•ă‚ŒăŸé …ç›®ă¯æœªå®Œäº†ă«ăªă‚ă¾ă™. Translate also finished entries - + 完了ă—ă¦ă„ă‚‹é …ç›®ă‚‚ç¿»è¨³ă™ă‚‹ Phrase book preference - ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă®å„ªå…ˆåº¦ + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă®è¨­å® Move up - ä¸ă«ç§»å‹• + ä¸ă«ç§»å‹• Move down - 下ă«ç§»å‹• + 下ă«ç§»å‹• The batch translator will search through the selected phrase books in the order given above. - + 一括翻訳機能ă¯ă€ä¸è¨˜ă§é¸æă•ă‚ŒăŸé †ă«ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’æ¤œç´¢ă—ă¾ă™ă€‚ &Run - 実行(&R) + 実行(&R) Cancel - ă‚­ăƒ£ăƒ³ă‚»ăƒ« + ă‚­ăƒ£ăƒ³ă‚»ăƒ« @@ -138,38 +138,39 @@ <qt>Duplicate messages found in '%1': - + <qt>'%1' ă«é‡è¤‡ă—ăŸăƒ¡ăƒƒă‚»ăƒ¼ă‚¸ăŒè¦‹ă¤ă‹ă‚ă¾ă—ăŸ: <p>[more duplicates omitted] - + <p>[ă•ă‚‰ă«é‡è¤‡ă—ă¦ă„ă‚‹éƒ¨åˆ†ă¯çœç•¥ă•ă‚Œă¾ă—ăŸ] <p>* Context: %1<br>* Source: %2 - + <p>* ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆ: %1<br>* ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆ: %2 <br>* Comment: %3 - + <br>* ă‚³ăƒ¡ăƒ³ăƒˆ: %3 Linguist does not know the plural rules for '%1'. Will assume a single universal form. - + Linguist ă¯'%1'ă®è¤‡æ•°ă®ăƒ«ăƒ¼ăƒ«ă‚’知ă‚ă¾ă›ă‚“。 +å˜ä¸€ă®å…±é€å½¢å¼ă¨ă¿ăªă—ă¾ă™ă€‚ Cannot create '%2': %1 - + '%2' ă‚’ä½œæˆă§ăă¾ă›ă‚“: %1 Universal Form - + å…±é€å½¢å¼ @@ -200,37 +201,37 @@ Will assume a single universal form. Accelerator possibly superfluous in translation. - 訳ă«ä½™åˆ†ăªă‚¢ă‚¯ă‚»ăƒ©ăƒ¬ăƒ¼ă‚¿ăŒă¤ă„ă¦ă„ă¾ă™ă€‚ + 訳ă«ä½™åˆ†ăªă‚¢ă‚¯ă‚»ăƒ©ăƒ¬ăƒ¼ă‚¿ăŒă¤ă„ă¦ă„ă¾ă™ă€‚ Accelerator possibly missing in translation. - 訳ă«ă‚¢ă‚¯ă‚»ăƒ©ăƒ¬ăƒ¼ă‚¿ăŒæ¬ ă‘ă¦ă„ă¾ă™ă€‚ + 訳ă«ă‚¢ă‚¯ă‚»ăƒ©ăƒ¬ăƒ¼ă‚¿ăŒæ¬ ă‘ă¦ă„ă¾ă™ă€‚ Translation does not end with the same punctuation as the source text. - 訳ăŒă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă¨åŒă˜å¥èª­ç‚¹ă§çµ‚ă‚ă£ă¦ă„ă¾ă›ă‚“。 + 訳ăŒă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă¨åŒă˜å¥èª­ç‚¹ă§çµ‚ă‚ă£ă¦ă„ă¾ă›ă‚“。 A phrase book suggestion for '%1' was ignored. - '%1' ă«ă¤ă„ă¦ă®ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă®ç¤ºå”†ă‚’無視ă—ă¦ă„ă¾ă™ă€‚ + '%1' ă«ă¤ă„ă¦ă®ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă®ç¤ºå”†ă‚’無視ă—ă¦ă„ă¾ă™ă€‚ Translation does not refer to the same place markers as in the source text. - 訳èªă«ă¯ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă¨åŒă˜æ•°ă® "%" ăŒă‚ă‚ă¾ă›ă‚“。 + 訳èªă«ă¯ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă¨åŒă˜æ•°ă® "%" ăŒă‚ă‚ă¾ă›ă‚“。 Translation does not contain the necessary %n place marker. - + 訳èªă«å¿…è¦ăª %n 個ă®ăƒ—ăƒ¬ăƒ¼ă‚¹ăƒăƒ¼ă‚«ăƒ¼ "%" ăŒă‚ă‚ă¾ă›ă‚“。 Unknown error - + 未知ă®ă‚¨ăƒ©ăƒ¼ @@ -248,37 +249,37 @@ Will assume a single universal form. Find - + 検索 &Find what: - + 検索ă™ă‚‹æ–‡å­—列(&F): &Source texts - + ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆ(&S) &Translations - + 訳èª(&T) &Match case - + 大/å°æ–‡å­—ă®åŒºåˆ¥(&M) &Comments - + ă‚³ăƒ¡ăƒ³ăƒˆ(&C) Ignore &accelerators - + ă‚¢ă‚¯ă‚»ăƒ©ăƒ¬ăƒ¼ă‚¿ă‚’ç„¡è¦–(&A) @@ -388,16 +389,18 @@ Will assume a single universal form. Generated %n translation(s) (%1 finished and %2 unfinished) - - + + %n 件ă®è¨³èª (%1 件ăŒå®Œäº†ă€ %2 件ăŒæœªå®Œäº†) ă‚’ç”Ÿæˆă—ă¾ă—ăŸ + Ignored %n untranslated source text(s) - - + + %n 件ă®æœªç¿»è¨³ă®ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă‚’無視ă—ă¾ă—ăŸ + @@ -413,12 +416,12 @@ Will assume a single universal form. About Qt - Qt ă«ă¤ă„ă¦(&Q) + Qt ă«ă¤ă„㦠About Qt Linguist - Qt Linguist ă«ă¤ă„ă¦(&A) + Qt Linguist ă«ă¤ă„㦠@@ -476,7 +479,7 @@ Will assume a single universal form. Create a new phrase book. - æ–°ă—ă„ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’ä½œæˆ + æ–°ă—ă„ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’ä½œæˆă—ă¾ă™ă€‚ @@ -545,12 +548,12 @@ Will assume a single universal form. Open Read-O&nly... - + 読å–専用ă§é–‹ă(&N)... &Save All - + å…¨ă¦ä¿å­˜(&S) @@ -584,7 +587,7 @@ Will assume a single universal form. Recently Opened &Files - + 最近使ă£ăŸăƒ•ă‚¡ă‚¤ăƒ«(&F) @@ -625,7 +628,7 @@ Will assume a single universal form. &Edit Phrase Book - ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’ç·¨é›†(&E)... + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’ç·¨é›†(&E) @@ -696,7 +699,7 @@ Will assume a single universal form. MainWindow - ăƒ¡ă‚¤ăƒ³ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦ + MainWindow @@ -753,7 +756,7 @@ Will assume a single universal form. Open a Qt translation source file (TS file) for editing - Qt ç¿»è¨³ă‚½ăƒ¼ă‚¹ăƒ•ă‚¡ă‚¤ăƒ« (TS ăƒ•ă‚¡ă‚¤ăƒ«) を編集用ă«é–‹ăă¾ă™ă€‚ + Qt ç¿»è¨³ă‚½ăƒ¼ă‚¹ăƒ•ă‚¡ă‚¤ăƒ« (TS ăƒ•ă‚¡ă‚¤ăƒ«) を編集用ă«é–‹ăă¾ă™ &Open Phrase Book @@ -810,7 +813,7 @@ Will assume a single universal form. &Print Phrase Book - ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’å°åˆ·(&P)... + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’å°åˆ·(&P) Re&cently opened files @@ -856,172 +859,176 @@ Will assume a single universal form. Source text - ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆ + ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆ Index - + ă‚¤ăƒ³ăƒ‡ăƒƒă‚¯ă‚¹ Context - ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆ + ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆ Items - 項目数 + 項目数 This panel lists the source contexts. - ă“ă®ăƒ‘ăƒăƒ«ă§ă¯ă‚½ăƒ¼ă‚¹ă®ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆă‚’一覧表示ă—ă¦ă„ă¾ă™ă€‚ + ă“ă®ăƒ‘ăƒăƒ«ă§ă¯ă‚½ăƒ¼ă‚¹ă®ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆă‚’一覧表示ă—ă¦ă„ă¾ă™ă€‚ Strings - + 文字列 Phrases and guesses - + ăƒ•ăƒ¬ăƒ¼ă‚ºă¨æ¨æ¸¬ Sources and Forms - + ă‚½ăƒ¼ă‚¹ă¨ăƒ•ă‚©ăƒ¼ăƒ  Warnings - + è­¦å‘ MOD status bar: file(s) modified - + MOD Loading... - ăƒ­ăƒ¼ăƒ‰ă—ă¦ă„ă¾ă™... + ăƒ­ăƒ¼ăƒ‰ă—ă¦ă„ă¾ă™... Loading File - Qt Linguist - + ăƒ­ăƒ¼ăƒ‰ă—ă¦ă„ă¾ă™ - Qt Linguist The file '%1' does not seem to be related to the currently open file(s) '%2'. Close the open file(s) first? - + ăƒ•ă‚¡ă‚¤ăƒ« '%1' ă¯ă€æ—¢ă«é–‹ă„ă¦ă„ă‚‹ăƒ•ă‚¡ă‚¤ăƒ« '%2' ă¨ă¯é–¢é€£ă—ă¦ă„ăªă„ă‚ˆă†ă§ă™ă€‚ + +å…ˆă«é–‹ă„ăŸăƒ•ă‚¡ă‚¤ăƒ«ă‚’é–‰ă˜ă¾ă™ă‹? The file '%1' does not seem to be related to the file '%2' which is being loaded as well. Skip loading the first named file? - + ăƒ•ă‚¡ă‚¤ăƒ« '%1' ă¯ă€æ—¢ă«ăƒ­ăƒ¼ăƒ‰ă•ă‚Œă¦ă„ă‚‹ăƒ•ă‚¡ă‚¤ăƒ« '%2' ă¨ă¯é–¢é€£ă—ă¦ă„ăªă„ă‚ˆă†ă§ă™ă€‚ + +ăƒ•ă‚¡ă‚¤ăƒ«ă®ăƒ­ăƒ¼ăƒ‰ă‚’ă‚¹ă‚­ăƒƒăƒ—ă—ă¾ă™ă‹? %n translation unit(s) loaded. - - + + %n 件ă®ç¿»è¨³é …ç›®ă‚’ăƒ­ăƒ¼ăƒ‰ă—ă¾ă—ăŸă€‚ Related files (%1);; - + %1 ă«é–¢é€£ă—ăŸăƒ•ă‚¡ă‚¤ăƒ«;; Open Translation Files - + ç¿»è¨³ăƒ•ă‚¡ă‚¤ăƒ«ă‚’é–‹ă File saved. - ăƒ•ă‚¡ă‚¤ăƒ«ăŒä¿å­˜ă•ă‚Œă¾ă—ăŸă€‚ + ăƒ•ă‚¡ă‚¤ăƒ«ăŒä¿å­˜ă•ă‚Œă¾ă—ăŸă€‚ Release - ăƒªăƒªăƒ¼ă‚¹ + ăƒªăƒªăƒ¼ă‚¹ Qt message files for released applications (*.qm) All files (*) - ăƒªăƒªăƒ¼ă‚¹ă•ă‚ŒăŸă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ç”¨ă® Qt ăƒ¡ăƒƒă‚»ăƒ¼ă‚¸ăƒ•ă‚¡ă‚¤ăƒ« (*.qm) + ăƒªăƒªăƒ¼ă‚¹ă•ă‚ŒăŸă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ç”¨ă® Qt ăƒ¡ăƒƒă‚»ăƒ¼ă‚¸ăƒ•ă‚¡ă‚¤ăƒ« (*.qm) ă™ă¹ă¦ă®ăƒ•ă‚¡ă‚¤ăƒ« (*) File created. - ăƒ•ă‚¡ă‚¤ăƒ«ăŒä½œæˆă•ă‚Œă¾ă—ăŸă€‚ + ăƒ•ă‚¡ă‚¤ăƒ«ăŒä½œæˆă•ă‚Œă¾ă—ăŸă€‚ Printing... - å°åˆ·ä¸­... + å°åˆ·ä¸­... Context: %1 - ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆ: %1 + ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆ: %1 finished - 完了 + 完了 unresolved - 未解決 + 未解決 obsolete - ă“ă®ăƒăƒ¼ă‚¸ăƒ§ăƒ³ă§ă¯ä½¿ă‚ă‚Œă¦ă„ăªă„ + ă“ă®ăƒăƒ¼ă‚¸ăƒ§ăƒ³ă§ă¯ä½¿ă‚ă‚Œă¦ă„ăªă„ Printing... (page %1) - å°åˆ·ä¸­... (%1 ăƒăƒ¼ă‚¸) + å°åˆ·ä¸­... (%1 ăƒăƒ¼ă‚¸) Printing completed - å°åˆ·å®Œäº† + å°åˆ·å®Œäº† Printing aborted - å°åˆ·ä¸­æ­¢ + å°åˆ·ä¸­æ­¢ Search wrapped. - 検索ăŒä¸€é€ă‚終ă‚ă‚ă¾ă—ăŸă€‚ + 検索ăŒä¸€é€ă‚終ă‚ă‚ă¾ă—ăŸă€‚ @@ -1035,13 +1042,13 @@ All files (*) Qt Linguist - Qt Linguist + Qt Linguist Cannot find the string '%1'. - 文字列 '%1' ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“。 + 文字列 '%1' ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“。 Translate @@ -1056,58 +1063,58 @@ All files (*) Search And Translate in '%1' - Qt Linguist - + '%1' 内ă§æ¤œç´¢ă—ă¦ç¿»è¨³ - Qt Linguist Translate - Qt Linguist - + 翻訳 - Qt Linguist Translated %n entry(s) - - + + %n é …ç›®ăŒç¿»è¨³æ¸ˆă¿ă§ă™ No more occurrences of '%1'. Start over? - + '%1' ă¯ă€ă“ă‚Œä»¥ä¸è¦‹ă¤ă‹ă‚ă¾ă›ă‚“ă€‚å…ˆé ­ă«æˆ»ă‚ă¾ă™ă‹? Create New Phrase Book - æ–°ă—ă„ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’ä½œæˆ + æ–°ă—ă„ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’ä½œæˆ Qt phrase books (*.qph) All files (*) - Qt ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ (*.qph) -ă™ă¹ă¦ă®ăƒ•ă‚¡ă‚¤ăƒ« (*) + Qt ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ (*.qph) +å…¨ă¦ă®ăƒ•ă‚¡ă‚¤ăƒ« (*) Phrase book created. - ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ăŒä½œæˆă•ă‚Œă¾ă—ăŸă€‚ + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ăŒä½œæˆă•ă‚Œă¾ă—ăŸă€‚ Open Phrase Book - ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’é–‹ă + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’é–‹ă Qt phrase books (*.qph);;All files (*) - + Qt ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ (*.qph);;ă™ă¹ă¦ă®ăƒ•ă‚¡ă‚¤ăƒ« (*) %n phrase(s) loaded. - + %n é …ç›®ă®ăƒ•ăƒ¬ăƒ¼ă‚ºăŒăƒ­ăƒ¼ăƒ‰ă•ă‚Œă¾ă—ăŸă€‚ @@ -1116,32 +1123,32 @@ All files (*) Add to phrase book - + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă«è¿½å  No appropriate phrasebook found. - + é©åˆ‡ăªăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“。 Adding entry to phrasebook %1 - + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ %1 ă«é …ç›®ă‚’è¿½å  Select phrase book to add to - + 追å å…ˆă®ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’é¸æă—ă¦ăă ă•ă„ Unable to launch Qt Assistant (%1) - + Qt Assistant (%1) ă‚’èµ·å‹•ă§ăă¾ă›ă‚“ Version %1 - ăƒăƒ¼ă‚¸ăƒ§ăƒ³ %1 + ăƒăƒ¼ă‚¸ăƒ§ăƒ³ %1 Open Source Edition @@ -1158,83 +1165,83 @@ All files (*) <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist is a tool for adding translations to Qt applications.</p><p>%2</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> - <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist ă¯ă€Qt ă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ă®ç¿»è¨³ă‚’è¡Œă†ăƒ„ăƒ¼ăƒ«ă§ă™ă€‚</p><p>%2</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). å…¨ă¦ă®æ¨©åˆ©ă¯ä¿è­·ă•ă‚Œă¦ă„ă¾ă™ă€‚</p><p>ă“ă®ăƒ—ăƒ­ă‚°ăƒ©ăƒ ă¯ă€ă€Œè¨­è¨ˆă€ă€ă€Œå¸‚場性ă€ăă‚ˆă³ă€Œç‰¹å®ă®ç›®ç„ă¸ă®é©åˆæ€§ă€ă‚‚å«ă‚€ă€ă‚らゆる種é¡ă®ă€Œä¿è¨¼ăŒăªăă€ă€ă€Œăă®ă¾ă¾ă§ă€æä¾›ă•ă‚Œă¾ă™ă€‚</p> + <center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist ă¯ă€Qt ă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ă®ç¿»è¨³ă‚’è¡Œă†ăƒ„ăƒ¼ăƒ«ă§ă™ă€‚</p><p>%2</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). å…¨ă¦ă®æ¨©åˆ©ă¯ä¿è­·ă•ă‚Œă¦ă„ă¾ă™ă€‚</p><p>ă“ă®ăƒ—ăƒ­ă‚°ăƒ©ăƒ ă¯ă€ă€Œè¨­è¨ˆă€ă€ă€Œå¸‚場性ă€ăă‚ˆă³ă€Œç‰¹å®ă®ç›®ç„ă¸ă®é©åˆæ€§ă€ă‚‚å«ă‚€ă€ă‚らゆる種é¡ă®ă€Œä¿è¨¼ăŒăªăă€ă€ă€Œăă®ă¾ă¾ă§ă€æä¾›ă•ă‚Œă¾ă™ă€‚</p> Do you want to save the modified files? - + 変更ă•ă‚ŒăŸăƒ•ă‚¡ă‚¤ăƒ«ă‚’ä¿å­˜ă—ă¾ă™ă‹? Do you want to save '%1'? - '%1' ă‚’ä¿å­˜ă—ă¾ă™ă‹? + '%1' ă‚’ä¿å­˜ă—ă¾ă™ă‹? Qt Linguist[*] - + Qt Linguist[*] %1[*] - Qt Linguist - + %1[*] - Qt Linguist No untranslated translation units left. - + 未訳項目ă¯æ®‹ă£ă¦ă„ă¾ă›ă‚“。 &Window - ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦(&W) + ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦(&W) Minimize - 最å°åŒ– + 最å°åŒ– Ctrl+M - Ctrl+M + Ctrl+M Display the manual for %1. - %1 ă®ăƒăƒ‹ăƒ¥ă‚¢ăƒ«ă‚’表示ă—ă¾ă™ă€‚ + %1 ă®ăƒăƒ‹ăƒ¥ă‚¢ăƒ«ă‚’表示ă—ă¾ă™ă€‚ Display information about %1. - %1 ă«ă¤ă„ă¦ă®æƒ…å ±ă‚’è¡¨ç¤ºă—ă¾ă™ă€‚ + %1 ă«ă¤ă„ă¦ă®æƒ…å ±ă‚’è¡¨ç¤ºă—ă¾ă™ă€‚ &Save '%1' - + '%1' ă‚’ä¿å­˜ă™ă‚‹(&S) Save '%1' &As... - + '%1' ă‚’åå‰ă‚’付ă‘ă¦ä¿å­˜(&A)... Release '%1' - + '%1' ă‚’ăƒªăƒªăƒ¼ă‚¹ Release '%1' As... - + '%1' ă‚’åå‰ă‚’付ă‘ă¦ăƒªăƒªăƒ¼ă‚¹... &Close '%1' - + '%1' ă‚’é–‰ă˜ă‚‹(&C) @@ -1253,78 +1260,78 @@ All files (*) &Close - é–‰ă˜ă‚‹(&C) + é–‰ă˜ă‚‹(&C) Save All - + å…¨ă¦ä¿å­˜ &Release All - + å…¨ă¦ăƒªăƒªăƒ¼ă‚¹(&R) Close All - ă™ă¹ă¦é–‰ă˜ă‚‹ + ă™ă¹ă¦é–‰ă˜ă‚‹ Translation File &Settings for '%1'... - + '%1' ă®ç¿»è¨³ăƒ•ă‚¡ă‚¤ăƒ«ă®è¨­å®(&S)... &Batch Translation of '%1'... - + '%1' ă®ä¸€æ‹¬ç¿»è¨³(&B)... Search And &Translate in '%1'... - + '%1' å†…ă‚’æ¤œç´¢ă—ă¦ç¿»è¨³(&T)... Search And &Translate... - + 検索ă—ă¦è¨³èªă‚’ç½®æ›(&T)... Cannot read from phrase book '%1'. - ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ '%1' ă‹ă‚‰èª­ă¿å‡ºă›ă¾ă›ă‚“。 + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ '%1' ă‹ă‚‰èª­ă¿å‡ºă›ă¾ă›ă‚“。 Close this phrase book. - ă“ă®ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’é–‰ă˜ă¾ă™ă€‚ + ă“ă®ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’é–‰ă˜ă¾ă™ă€‚ Enables you to add, modify, or delete entries in this phrase book. - + ă“ă®ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă§é …ç›®ă®è¿½å ă€å¤‰æ›´ă€å‰é™¤ăŒă§ăă¾ă™ă€‚ Print the entries in this phrase book. - + ă“ă®ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă®é …目をå°åˆ·ă—ă¾ă™ă€‚ Cannot create phrase book '%1'. - ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ '%1' ă‚’ä½œæˆă§ăă¾ă›ă‚“。 + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ '%1' ă‚’ä½œæˆă§ăă¾ă›ă‚“。 Do you want to save phrase book '%1'? - + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ '%1' ă‚’ä¿å­˜ă—ă¾ă™ă‹? All - + ă™ă¹ă¦ @@ -1468,194 +1475,194 @@ All files (*) &Open... - + é–‹ă(&O)... Save - + ä¿å­˜ &Print... - + å°åˆ·(&P)... Print a list of all the translation units in the current translation source file. - + ç¾åœ¨ă® Qt ç¿»è¨³ă‚½ăƒ¼ă‚¹ăƒ•ă‚¡ă‚¤ăƒ«ă®å…¨ă¦ă®è¨³èªă®ä¸€è¦§ă‚’å°åˆ·ă—ă¾ă™ă€‚ Undo the last editing operation performed on the current translation. - + ç¾åœ¨ă®ç¿»è¨³ăƒ•ă‚¡ă‚¤ăƒ«ă§æœ€å¾Œă«è¡Œă£ăŸç·¨é›†æ“ä½œă‚’å–ă‚消ă—ă¾ă™ă€‚ &Find... - + 検索(&F)... Previous unfinished item. - + å‰ă®æœªè¨³ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Move to the previous unfinished item. - + å‰ă®æœªå®Œäº†ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Next unfinished item. - + 次ă®æœªè¨³ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Move to the next unfinished item. - + 次ă®æœªå®Œäº†ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Move to previous item. - + å‰ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Move to the previous item. - + å‰ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Next item. - + 次ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Move to the next item. - + 次ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Mark item as done and move to the next unfinished item. - + ă“ă®é …ç›®ă«å®Œäº†ă®ăƒăƒ¼ă‚¯ă‚’ă¤ă‘ă€æ¬¡ă®æœªå®Œäº†ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Mark this item as done and move to the next unfinished item. - + ă“ă®é …ç›®ă«å®Œäº†ă®ăƒăƒ¼ă‚¯ă‚’ă¤ă‘ă€æ¬¡ă®æœªå®Œäº†ă®é …ç›®ă¸ç§»å‹•ă—ă¾ă™ă€‚ Copy from source text - + ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă‹ă‚‰ă‚³ăƒ”ăƒ¼ Toggle the validity check of accelerators. - + ă‚¢ă‚¯ă‚»ăƒ©ăƒ¬ăƒ¼ă‚¿ă®ăƒă‚§ăƒƒă‚¯ă‚’有å¹ă«ă™ă‚‹ă‹ă©ă†ă‹ă‚’切ă‚替ăˆă¾ă™ă€‚ Toggle the validity check of accelerators, i.e. whether the number of ampersands in the source and translation text is the same. If the check fails, a message is shown in the warnings window. - + ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă¨è¨³èªă®ă‚¢ă‚¯ă‚»ăƒ©ăƒ¬ăƒ¼ă‚¿ă®å€‹æ•°ăŒåŒă˜ă‹å¦ă‹ă®ăƒă‚§ăƒƒă‚¯ă‚’有å¹ă«ă™ă‚‹ă‹ă©ă†ă‹ă‚’切ă‚替ăˆă¾ă™ă€‚ăƒă‚§ăƒƒă‚¯ăŒç„¡å¹ă«ăªă£ă¦ă„ă¦ă‚‚ă€è­¦å‘ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦ă«ăƒ¡ăƒƒă‚»ăƒ¼ă‚¸ă¯è¡¨ç¤ºă•ă‚Œă¾ă™ă€‚ Toggle the validity check of ending punctuation. - + 末尾ă®å¥èª­ç‚¹ă®ăƒă‚§ăƒƒă‚¯ă‚’有å¹ă«ă™ă‚‹ă‹ă©ă†ă‹ă‚’切ă‚替ăˆă¾ă™ă€‚ Toggle the validity check of ending punctuation. If the check fails, a message is shown in the warnings window. - + 末尾ă®å¥èª­ç‚¹ă®ăƒă‚§ăƒƒă‚¯ă‚’有å¹ă«ă™ă‚‹ă‹ă©ă†ă‹ă‚’切ă‚替ăˆă¾ă™ă€‚ăƒă‚§ăƒƒă‚¯ăŒç„¡å¹ă«ăªă£ă¦ă„ă¦ă‚‚ă€è­¦å‘ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦ă«ăƒ¡ăƒƒă‚»ăƒ¼ă‚¸ăŒè¡¨ç¤ºă•ă‚Œă¾ă™ă€‚ Toggle checking that phrase suggestions are used. If the check fails, a message is shown in the warnings window. - + ăƒ•ăƒ¬ăƒ¼ă‚ºă®ç¤ºå”†ă‚’使ă†ă‹ă©ă†ă‹ă®ăƒă‚§ăƒƒă‚¯ă‚’切ă‚替ăˆă¾ă™ă€‚ăƒă‚§ăƒƒă‚¯ăŒç„¡å¹ă«ăªă£ă¦ă„ă¦ă‚‚ă€è­¦å‘ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦ă«ăƒ¡ăƒƒă‚»ăƒ¼ă‚¸ăŒè¡¨ç¤ºă•ă‚Œă¾ă™ă€‚ Toggle the validity check of place markers. - + "%" ă®æ•°ă‚„番å·ă®ăƒă‚§ăƒƒă‚¯ă‚’è¡Œă†ă‹ă©ă†ă‹ă‚’切ă‚替ăˆă¾ă™ă€‚ Toggle the validity check of place markers, i.e. whether %1, %2, ... are used consistently in the source text and translation text. If the check fails, a message is shown in the warnings window. - + ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă¨è¨³èªă®"%1"ă‚„"%2"ç­‰ă®ăƒ—ăƒ¬ăƒ¼ă‚¹ăƒăƒ¼ă‚«ăƒ¼ă®æ•´åˆăŒå–ă‚Œă¦ă„ă‚‹ă‹å¦ă‹ă®ăƒă‚§ăƒƒă‚¯ă‚’è¡Œă†ă‹ă©ă†ă‹ă‚’切ă‚替ăˆă¾ă™ă€‚ăƒă‚§ăƒƒă‚¯ăŒç„¡å¹ă«ăªă£ă¦ă„ă¦ă‚‚ă€è­¦å‘ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦ă«ăƒ¡ăƒƒă‚»ăƒ¼ă‚¸ă¯è¡¨ç¤ºă•ă‚Œă¾ă™ă€‚ &New Phrase Book... - + æ–°ă—ă„ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯(&N)... &Open Phrase Book... - + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‚’é–‹ă(&O)... &Reset Sorting - + ă‚½ăƒ¼ăƒˆé †åºă‚’ăƒªă‚»ăƒƒăƒˆ(&R) Display translation statistics. - + 翻訳ă®çµ±è¨ˆă‚’表示ă—ă¾ă™ă€‚ &Search And Translate... - + 検索ă—ă¦è¨³èªă‚’ç½®æ›(&S)... Close - é–‰ă˜ă‚‹ + é–‰ă˜ă‚‹ &Close All - + å…¨ă¦é–‰ă˜ă‚‹(&C) Ctrl+W - + Ctrl+W &Batch Translation... - + 一括翻訳(&B)... Translation File &Settings... - + ç¿»è¨³ăƒ•ă‚¡ă‚¤ăƒ«ă®è¨­å®(&S)... &Add to Phrase Book - + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă«è¿½å (&A) Ctrl+T - + Ctrl+T Ctrl+J - + Ctrl+J Ctrl+Shift+J - + Ctrl+Shift+J @@ -1707,82 +1714,82 @@ All files (*) German - + German Japanese - + Japanese French - + French Polish - + Polish Chinese - + Chinese Source text - ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆ + ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆ Source text (Plural) - + ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆ(複数) This area shows the plural form of the source text. - + ă“ă®é ˜åŸŸă¯è¤‡æ•°ă®ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă‚’表示ă—ă¾ă™ă€‚ Developer comments - + 開発者ă®ă‚³ăƒ¡ăƒ³ăƒˆ This area shows a comment that may guide you, and the context in which the text occurs. - ă“ă®é ˜åŸŸă¯ă€æ‰‹å©ă‘ă¨ăªă‚‹ă‚³ăƒ¡ăƒ³ăƒˆă¨ă€ăƒ†ă‚­ă‚¹ăƒˆăŒå‡ºă¦ăă‚‹ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆă‚’è¡¨ç¤ºă—ă¾ă™ă€‚ + ă“ă®é ˜åŸŸă¯ă€æ‰‹å©ă‘ă¨ăªă‚‹ă‚³ăƒ¡ăƒ³ăƒˆă¨ă€ăƒ†ă‚­ă‚¹ăƒˆăŒå‡ºă¦ăă‚‹ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆă‚’è¡¨ç¤ºă—ă¾ă™ă€‚ Here you can enter comments for your own use. They have no effect on the translated applications. - + ă“ă“ă¯ă‚ăªăŸăŒè‡ªåˆ†è‡ªèº«ă®ç‚ºă«ă‚³ăƒ¡ăƒ³ăƒˆă‚’å…¥å›ă§ăă¾ă™ă€‚翻訳ă•ă‚ŒăŸă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ă«ă¯ä½•ă®å½±éŸ¿ă‚‚ä¸ăˆă¾ă›ă‚“。 %1 translation (%2) - + %1 翻訳 (%2) This is where you can enter or modify the translation of the above source text. - + ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă®è¨³ă‚’å…¥å›ă—ăŸă‚変更ă—ăŸă‚ă§ăă‚‹ă¨ă“ă‚ă§ă™ă€‚ %1 translation - + %1 訳 %1 translator comments - + %1 翻訳者ă®ă‚³ăƒ¡ăƒ³ăƒˆ This area shows the source text. - ă“ă®é ˜åŸŸă¯ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă‚’表示ă—ă¾ă™ă€‚ + ă“ă®é ˜åŸŸă¯ă‚½ăƒ¼ă‚¹ăƒ†ă‚­ă‚¹ăƒˆă‚’表示ă—ă¾ă™ă€‚ This is where you can enter or modify the translation of some source text. @@ -1801,7 +1808,8 @@ All files (*) '%1' Line: %2 - + '%1' +行番å·: %2 @@ -1821,22 +1829,22 @@ Line: %2 Completion status for %1 - + %1 ă®ç¿»è¨³å®Œäº†ç¶æ³ <file header> - + <ăƒ•ă‚¡ă‚¤ăƒ« ăƒ˜ăƒƒăƒ€ăƒ¼> <context comment> - + <ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆ ă‚³ăƒ¡ăƒ³ăƒˆ> <unnamed context> - + <ç„¡åă®ă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆ> @@ -1871,7 +1879,7 @@ Line: %2 %1[*] - Qt Linguist - + %1[*] - Qt Linguist @@ -1886,27 +1894,27 @@ Line: %2 &New Entry - + æ–°ă—ă„é …ç›®(&N) Click here to remove the entry from the phrase book. - + ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă‹ă‚‰ăƒ•ăƒ¬ăƒ¼ă‚ºă‚’消å»ă™ă‚‹ă«ă¯ă“ă“ă‚’ă‚¯ăƒªăƒƒă‚¯ă—ă¦ăă ă•ă„。 &Remove Entry - + 項目をå‰é™¤(&R) Settin&gs... - + 設å®(&G)... Click here to close this window. - ă“ă®ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦ă‚’é–‰ă˜ă‚‹ă«ă¯ă“ă“ă‚’ă‚¯ăƒªăƒƒă‚¯ă—ă¦ăă ă•ă„。 + ă“ă®ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦ă‚’é–‰ă˜ă‚‹ă«ă¯ă“ă“ă‚’ă‚¯ăƒªăƒƒă‚¯ă—ă¾ă™ă€‚ Click here to remove the phrase from the phrase book. @@ -1958,7 +1966,7 @@ Line: %2 This window allows you to add, modify, or delete entries in a phrase book. - + ă“ă®ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦ă§ăƒ•ăƒ¬ăƒ¼ă‚ºăƒ–ăƒƒă‚¯ă«ăƒ•ăƒ¬ăƒ¼ă‚ºă‚’追å ă€å¤‰æ›´ă€å‰é™¤ă§ăă¾ă™ă€‚ @@ -2006,7 +2014,7 @@ Line: %2 Translation - 訳 + 翻訳 @@ -2014,22 +2022,22 @@ Line: %2 Insert - + 挿入 Edit - 編集 + 編集 Guess (%1) - æ¨æ¸¬(%1) + æ¨æ¸¬(%1) Guess - æ¨æ¸¬ + æ¨æ¸¬ @@ -2037,17 +2045,17 @@ Line: %2 Compiled Qt translations - + ă‚³ăƒ³ăƒ‘ă‚¤ăƒ«æ¸ˆă¿ Qt ç¿»è¨³ăƒ•ă‚¡ă‚¤ăƒ« Translation files (%1);; - + ç¿»è¨³ăƒ•ă‚¡ă‚¤ăƒ« (%1);; All files (*) - + ă™ă¹ă¦ă®ăƒ•ă‚¡ă‚¤ăƒ« (*) @@ -2063,57 +2071,57 @@ Line: %2 C++ source files - + C++ ă‚½ăƒ¼ă‚¹ăƒ•ă‚¡ă‚¤ăƒ« Java source files - + Java ă‚½ăƒ¼ă‚¹ăƒ•ă‚¡ă‚¤ăƒ« GNU Gettext localization files - + GNU Gettext 日本èªåŒ–ăƒ•ă‚¡ă‚¤ăƒ« Qt Script source files - + Qt ă‚¹ă‚¯ăƒªăƒ—ăƒˆ ă‚½ăƒ¼ă‚¹ăƒ•ă‚¡ă‚¤ăƒ« Qt translation sources (format 1.1) - + Qt ç¿»è¨³ă‚½ăƒ¼ă‚¹ (1.1å½¢å¼) Qt translation sources (format 2.0) - + Qt ç¿»è¨³ă‚½ăƒ¼ă‚¹ (2.0å½¢å¼) Qt translation sources (latest format) - + Qt ç¿»è¨³ă‚½ăƒ¼ă‚¹ (最新ă®å½¢å¼) Qt Designer form files - + Qt ăƒ‡ă‚¶ă‚¤ăƒ ăƒ•ă‚©ăƒ¼ăƒ ăƒ•ă‚¡ă‚¤ăƒ« Qt Jambi form files - + Qt Jambi ăƒ•ă‚©ăƒ¼ăƒ ăƒ•ă‚¡ă‚¤ăƒ« XLIFF localization files - + XLIFF 日本èªåŒ–ăƒ•ă‚¡ă‚¤ăƒ« Qt Linguist 'Phrase Book' - + Qt Linguist 'ăƒ•ăƒ¬ăƒ¼ă‚º ăƒ–ăƒƒă‚¯' @@ -2147,17 +2155,17 @@ Line: %2 <i>Source code not available</i> - + <i>ă‚½ăƒ¼ă‚¹ ă‚³ăƒ¼ăƒ‰ă¯ä½¿ç”¨ă§ăă¾ă›ă‚“</i> <i>File %1 not available</i> - + <i>ăƒ•ă‚¡ă‚¤ăƒ« %1 ăŒä½¿ç”¨ă§ăă¾ă›ă‚“</i> <i>File %1 not readable</i> - + <i>ăƒ•ă‚¡ă‚¤ăƒ« %1 ăŒèª­ă¿è¾¼ă‚ă¾ă›ă‚“</i> @@ -2213,7 +2221,7 @@ Line: %2 Translation - 訳 + 翻訳 @@ -2223,7 +2231,7 @@ Line: %2 Close - é–‰ă˜ă‚‹ + é–‰ă˜ă‚‹ @@ -2656,7 +2664,7 @@ All files (*) Texts such as 'TeX' and 'tex' are considered as different when checked. - ă“ă‚Œă‚’é¸æă™ă‚‹ă¨ă€ăŸă¨ăˆă° 'TeX' 㨠'tex' ă¯ç•°ăªă‚‹ă‚‚ă®ă¨è¦‹ăªă•ă‚Œă¾ă™ă€‚ + é¸æă™ă‚‹ă¨ă€ăŸă¨ăˆă° 'TeX' 㨠'tex' ă¯ç•°ăªă‚‹ă‚‚ă®ă¨è¦‹ăªă•ă‚Œă¾ă™ă€‚ @@ -2714,27 +2722,27 @@ All files (*) Settings for '%1' - Qt Linguist - + '%1' ă®è¨­å® - Qt Linguist Source language - + 翻訳元ă®è¨€èª Language - è¨€èª + è¨€èª Country/Region - + 国/地域 Target language - 翻訳先ă®è¨€èª + 翻訳先ă®è¨€èª -- cgit v0.12 From 531274c741aed51946398a30a7be691ef98999bf Mon Sep 17 00:00:00 2001 From: Lincoln Ramsay Date: Mon, 25 May 2009 15:46:50 +1000 Subject: BT: Clean up Mac -arch handling Instead of the multiple character-string replacements, just check for the discrete -arch values that we want to find. This makes the code clearer and should reduce the chance of subtle errors. Reviewed-by: Jason McDonald --- configure | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/configure b/configure index 32efd86..4cf7499 100755 --- a/configure +++ b/configure @@ -2703,23 +2703,24 @@ fi if [ "$PLATFORM_MAC" = "yes" ]; then # check -arch arguments for validity. ALLOWED="x86 ppc x86_64 ppc64 i386" - for i in $CFG_MAC_ARCHS + # Save the list so we can re-write it using only valid values + CFG_MAC_ARCHS_IN="$CFG_MAC_ARCHS" + CFG_MAC_ARCHS= + for i in $CFG_MAC_ARCHS_IN do if echo "$ALLOWED" | grep -w -v "$i" > /dev/null 2>&1; then echo "Unknown architecture: \"$i\". Supported architectures: x86[i386] ppc x86_64 ppc64"; exit 2; fi - done - -# replace "i386" with "x86" to support configuring with -arch i386 as an alias for x86. - CFG_MAC_ARCHS="${CFG_MAC_ARCHS/i386/x86}" - -# Build commmand line arguments we can pass to the compiler during configure tests -# by prefixing each arch with "-arch". - CFG_MAC_ARCHS_GCC_FORMAT="${CFG_MAC_ARCHS/x86/i386}" - CFG_MAC_ARCHS_GCC_FORMAT="${CFG_MAC_ARCHS_GCC_FORMAT/i386_64/x86_64}" - for ARCH in $CFG_MAC_ARCHS_GCC_FORMAT; do - MAC_ARCHS_COMMANDLINE="$MAC_ARCHS_COMMANDLINE -arch $ARCH" + if [ "$i" = "i386" -o "$i" = "x86" ]; then + # These are synonymous values + # CFG_MAC_ARCHS requires x86 while GCC requires i386 + CFG_MAC_ARCHS="$CFG_MAC_ARCHS x86" + MAC_ARCHS_COMMANDLINE="$MAC_ARCHS_COMMANDLINE -arch i386" + else + CFG_MAC_ARCHS="$CFG_MAC_ARCHS $i" + MAC_ARCHS_COMMANDLINE="$MAC_ARCHS_COMMANDLINE -arch $i" + fi done fi @@ -4129,14 +4130,14 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS \$(CARBON_CFLAGS)" EXTRA_OBJS="qsettings_mac.o qcore_mac.o" EXTRA_SRCS="\"$relpath/src/corelib/io/qsettings_mac.cpp\" \"$relpath/src/corelib/kernel/qcore_mac.cpp\"" - if echo "$CFG_MAC_ARCHS" | grep x86 > /dev/null 2>&1; then + if echo "$CFG_MAC_ARCHS" | grep x86 > /dev/null 2>&1; then # matches both x86 and x86_64 X86_CFLAGS="-arch i386" X86_LFLAGS="-arch i386" EXTRA_CFLAGS="$X86_CFLAGS $EXTRA_CFLAGS" EXTRA_CXXFLAGS="$X86_CFLAGS $EXTRA_CXXFLAGS" EXTRA_LFLAGS="$EXTRA_LFLAGS $X86_LFLAGS" fi - if echo "$CFG_MAC_ARCHS" | grep ppc > /dev/null 2>&1; then + if echo "$CFG_MAC_ARCHS" | grep ppc > /dev/null 2>&1; then # matches both ppc and ppc64 PPC_CFLAGS="-arch ppc" PPC_LFLAGS="-arch ppc" EXTRA_CFLAGS="$PPC_CFLAGS $EXTRA_CFLAGS" -- cgit v0.12 From afb81a7527d798618b03319d4c0c47d33487fcfa Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 25 May 2009 08:48:25 +0200 Subject: Fix a mistake in the doc. Reviewed-by: TrustMe --- src/gui/image/qpixmapcache.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index eb1ebd1..31d29d6 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -491,8 +491,7 @@ bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap) /*! Inserts a copy of the pixmap \a pm into - the cache and return you the key. The key is always greater than 0. - If the key is equals 0 then the insertion failed. + the cache and return you the key. When a pixmap is inserted and the cache is about to exceed its limit, it removes pixmaps until there is enough room for the -- cgit v0.12 From 4147a2c788c39f09ef87181768a779cb701fd2bd Mon Sep 17 00:00:00 2001 From: jasplin Date: Mon, 25 May 2009 09:25:43 +0200 Subject: Added a "Qt 5 FIXME" comment to qmessagebox.h. QMessageBox::question() has the wrong default value for one of its arguments, but fixing it may break existing code, and the workaround is trivial (just specify an explicit value for the default argument). Reviewed-by: TrustMe Task-number: 254131 --- src/gui/dialogs/qmessagebox.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/dialogs/qmessagebox.h b/src/gui/dialogs/qmessagebox.h index 8d9b9fa..c6fb3bc 100644 --- a/src/gui/dialogs/qmessagebox.h +++ b/src/gui/dialogs/qmessagebox.h @@ -191,6 +191,8 @@ public: static StandardButton information(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton); + // ### Qt 5: Replace Ok with Yes|No in question() function. + // Also consider if Ok == Yes and Cancel == No. static StandardButton question(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton); -- cgit v0.12 From 878ccb0645e7f1416daeddd6acdc37fea16b5e25 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 25 May 2009 10:12:27 +0200 Subject: qdoc: Added some missing qdoc comments. Task-number: 252493 --- src/gui/painting/qcolormap_mac.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/painting/qcolormap_mac.cpp b/src/gui/painting/qcolormap_mac.cpp index 96da90f..afe0378 100644 --- a/src/gui/painting/qcolormap_mac.cpp +++ b/src/gui/painting/qcolormap_mac.cpp @@ -55,11 +55,17 @@ public: }; static QColormap *qt_mac_global_map = 0; +/*! + Creates the class's internal colormap. + */ void QColormap::initialize() { qt_mac_global_map = new QColormap; } +/*! + Deletes the class's internal colormap. + */ void QColormap::cleanup() { delete qt_mac_global_map; -- cgit v0.12 From f8d4c07981e556bf416ccd75e7c460a0b84e4e98 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 25 May 2009 10:32:42 +0200 Subject: Fixed compilation Solaris. --- tools/designer/src/lib/shared/qdesigner_toolbar.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tools/designer/src/lib/shared/qdesigner_toolbar.cpp b/tools/designer/src/lib/shared/qdesigner_toolbar.cpp index 0bb91ee..898be1e 100644 --- a/tools/designer/src/lib/shared/qdesigner_toolbar.cpp +++ b/tools/designer/src/lib/shared/qdesigner_toolbar.cpp @@ -440,18 +440,14 @@ QAction *ToolBarEventFilter::actionAt(const QToolBar *tb, const QPoint &pos) return tb->actions().at(index); } +//that's a trick to get acces to the initStyleOption which is a protected member +class FriendlyToolBar : public QToolBar { +public: + friend class ToolBarEventFilter; +}; + QRect ToolBarEventFilter::handleArea(const QToolBar *tb) { - //that's a trick to get acces to the initStyleOption which is a protected member - class FriendlyToolBar : public QToolBar - { - public: -#ifdef Q_NO_USING_KEYWORD - void initStyleOption(QStyleOptionToolBar *option) { QToolBar::initStyleOption(option); } -#else - using QToolBar::initStyleOption; -#endif - }; QStyleOptionToolBar opt; static_cast(tb)->initStyleOption(&opt); return tb->style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, tb); -- cgit v0.12 From 943b709a71b1ffc9abdf459269c79dd1b731d781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 19 May 2009 09:55:08 +0200 Subject: Made PixelBuffer/FramebufferObject report correct DPI based metrics. We need to use both qt_defaultDpiX and qt_defaultDpiY, and round the resulting metric values. Reviewed-by: Trond --- src/opengl/qglframebufferobject.cpp | 15 ++++++++------- src/opengl/qglpixelbuffer.cpp | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index f6857ac..8af9f63 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -985,15 +985,16 @@ void QGLFramebufferObject::drawTexture(const QPointF &point, QMacCompatGLuint te } #endif -extern int qt_defaultDpi(); +extern int qt_defaultDpiX(); +extern int qt_defaultDpiY(); /*! \reimp */ int QGLFramebufferObject::metric(PaintDeviceMetric metric) const { Q_D(const QGLFramebufferObject); - float dpmx = qt_defaultDpi()*100./2.54; - float dpmy = qt_defaultDpi()*100./2.54; + float dpmx = qt_defaultDpiX()*100./2.54; + float dpmy = qt_defaultDpiY()*100./2.54; int w = d->size.width(); int h = d->size.height(); switch (metric) { @@ -1016,16 +1017,16 @@ int QGLFramebufferObject::metric(PaintDeviceMetric metric) const return 32;//d->depth; case PdmDpiX: - return (int)(dpmx * 0.0254); + return qRound(dpmx * 0.0254); case PdmDpiY: - return (int)(dpmy * 0.0254); + return qRound(dpmy * 0.0254); case PdmPhysicalDpiX: - return (int)(dpmx * 0.0254); + return qRound(dpmx * 0.0254); case PdmPhysicalDpiY: - return (int)(dpmy * 0.0254); + return qRound(dpmy * 0.0254); default: qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric); diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index ce7e9bd..efc58f2 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -388,15 +388,16 @@ QPaintEngine *QGLPixelBuffer::paintEngine() const #endif } -extern int qt_defaultDpi(); +extern int qt_defaultDpiX(); +extern int qt_defaultDpiY(); /*! \reimp */ int QGLPixelBuffer::metric(PaintDeviceMetric metric) const { Q_D(const QGLPixelBuffer); - float dpmx = qt_defaultDpi()*100./2.54; - float dpmy = qt_defaultDpi()*100./2.54; + float dpmx = qt_defaultDpiX()*100./2.54; + float dpmy = qt_defaultDpiY()*100./2.54; int w = d->req_size.width(); int h = d->req_size.height(); switch (metric) { @@ -419,16 +420,16 @@ int QGLPixelBuffer::metric(PaintDeviceMetric metric) const return 32;//d->depth; case PdmDpiX: - return (int)(dpmx * 0.0254); + return qRound(dpmx * 0.0254); case PdmDpiY: - return (int)(dpmy * 0.0254); + return qRound(dpmy * 0.0254); case PdmPhysicalDpiX: - return (int)(dpmx * 0.0254); + return qRound(dpmx * 0.0254); case PdmPhysicalDpiY: - return (int)(dpmy * 0.0254); + return qRound(dpmy * 0.0254); default: qWarning("QGLPixelBuffer::metric(), Unhandled metric type: %d\n", metric); -- cgit v0.12 From 886c537f2fa225eecc5a68670688e390445a3936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 25 May 2009 09:55:23 +0200 Subject: Fixed broken system clip handling in GL2 paint engine. Override systemStateChanged() to get the system clip updates. Reviewed-by: Trond --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 11 +++++++++++ src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 2 -- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index caf744a..f174306 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -173,6 +173,7 @@ public: // Clipping & state stuff stolen from QOpenGLPaintEngine: void updateDepthClip(); + void systemStateChanged(); uint use_system_clip : 1; QPaintEngine *last_engine; @@ -1302,6 +1303,16 @@ void QGL2PaintEngineEx::updateClipRegion(const QRegion &clipRegion, Qt::ClipOper d->updateDepthClip(); } +void QGL2PaintEngineExPrivate::systemStateChanged() +{ + Q_Q(QGL2PaintEngineEx); + use_system_clip = !systemClip.isEmpty(); + + if (q->painter()->hasClipping()) + q->updateClipRegion(q->painter()->clipRegion(), Qt::ReplaceClip); + else + q->updateClipRegion(QRegion(), Qt::NoClip); +} void QGL2PaintEngineExPrivate::updateDepthClip() { diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 76a4fe0..ccf89f0 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -119,6 +119,4 @@ private: Q_DISABLE_COPY(QGL2PaintEngineEx) }; - - #endif -- cgit v0.12 From 7c0073aaa23769a9e9ec08d595190ce61227ae8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 19 May 2009 15:23:07 +0200 Subject: Fixed bug in uninitialized GL pixmaps. When not setting filtering mode to GL_NEAREST/GL_LINEAR copying back from FBO to texture fails for some reason. Reviewed-by: Trond --- src/opengl/qpixmapdata_gl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index e3af864..c89b99b 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -167,6 +167,8 @@ void QGLPixmapData::ensureCreated() const glBindTexture(target, m_textureId); glTexImage2D(target, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } if (!m_source.isNull()) { -- cgit v0.12 From fc0b94eb37f5aee0d4921f3c87c87527c5aa8585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 20 May 2009 10:17:12 +0200 Subject: Fixed bug in QPaintEngineEx::drawTiledPixmap fallback code. The brush transform needs to include the rect position. Reviewed-by: Trond --- src/gui/painting/qpaintengineex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 8eaad60..74338b6 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -778,7 +778,7 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con { QBrush brush(state()->pen.color(), pixmap); QTransform xform; - xform.translate(-s.x(), -s.y()); + xform.translate(r.x() - s.x(), r.y() - s.y()); brush.setTransform(xform); qreal pts[] = { r.x(), r.y(), -- cgit v0.12 From bd9197b8c344e2f259f5e1c08a746464a04687bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 20 May 2009 12:40:59 +0200 Subject: Introduced preserved swap buffer path in GL window surface. When a buffer swap leaves the back buffer intact we don't have to use an FBO or PB, but can render directly to the window's back buffer, yielding higher performance and depending less on extensions such as multisample FBOs and FBO blitting. Reviewed-by: Trond --- src/opengl/qwindowsurface_gl.cpp | 114 ++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 50 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 6fce3e3..a3422b5 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -102,16 +102,18 @@ QGLGraphicsSystem::QGLGraphicsSystem() int spec[16]; spec[i++] = GLX_RGBA; spec[i++] = GLX_DOUBLEBUFFER; -#if 0 - spec[i++] = GLX_DEPTH_SIZE; - spec[i++] = 8; - spec[i++] = GLX_STENCIL_SIZE; - spec[i++] = 8; - spec[i++] = GLX_SAMPLE_BUFFERS_ARB; - spec[i++] = 1; - spec[i++] = GLX_SAMPLES_ARB; - spec[i++] = 4; -#endif + + if (!qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull()) { + spec[i++] = GLX_DEPTH_SIZE; + spec[i++] = 8; + spec[i++] = GLX_STENCIL_SIZE; + spec[i++] = 8; + spec[i++] = GLX_SAMPLE_BUFFERS_ARB; + spec[i++] = 1; + spec[i++] = GLX_SAMPLES_ARB; + spec[i++] = 4; + } + spec[i++] = XNone; XVisualInfo *vi = glXChooseVisual(X11->display, X11->defaultScreen, spec); @@ -229,6 +231,7 @@ struct QGLWindowSurfacePrivate int tried_fbo : 1; int tried_pb : 1; + int destructive_swap_buffers : 1; QGLContext *ctx; @@ -252,6 +255,7 @@ QGLWindowSurface::QGLWindowSurface(QWidget *window) d_ptr->ctx = 0; d_ptr->tried_fbo = false; d_ptr->tried_pb = false; + d_ptr->destructive_swap_buffers = qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull(); } QGLWindowSurface::~QGLWindowSurface() @@ -342,6 +346,9 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); Q_ASSERT(parent); + if (!geometry().isValid()) + return; + hijackWindow(parent); QRect br = rgn.boundingRect().translated(offset); @@ -356,48 +363,50 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & if (context()->format().doubleBuffer()) { #if !defined(QT_OPENGL_ES_2) - glBindTexture(target, d_ptr->tex_id); + if (d_ptr->destructive_swap_buffers) { + glBindTexture(target, d_ptr->tex_id); - QVector rects = d_ptr->paintedRegion.rects(); - for (int i = 0; i < rects.size(); ++i) { - QRect br = rects.at(i); - if (br.isEmpty()) - continue; + QVector rects = d_ptr->paintedRegion.rects(); + for (int i = 0; i < rects.size(); ++i) { + QRect br = rects.at(i); + if (br.isEmpty()) + continue; - const uint bottom = window()->height() - (br.y() + br.height()); - glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height()); - } + const uint bottom = window()->height() - (br.y() + br.height()); + glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height()); + } - glBindTexture(target, 0); + glBindTexture(target, 0); - QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion; + QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion; - if (!dirtyRegion.isEmpty()) { - context()->makeCurrent(); + if (!dirtyRegion.isEmpty()) { + context()->makeCurrent(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); #ifndef QT_OPENGL_ES - glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999); + glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999); #else - glOrthof(0, window()->width(), window()->height(), 0, -999999, 999999); + glOrthof(0, window()->width(), window()->height(), 0, -999999, 999999); #endif - glViewport(0, 0, window()->width(), window()->height()); + glViewport(0, 0, window()->width(), window()->height()); - QVector rects = dirtyRegion.rects(); - glColor4f(1, 1, 1, 1); - for (int i = 0; i < rects.size(); ++i) { - QRect rect = rects.at(i); - if (rect.isEmpty()) - continue; + QVector rects = dirtyRegion.rects(); + glColor4f(1, 1, 1, 1); + for (int i = 0; i < rects.size(); ++i) { + QRect rect = rects.at(i); + if (rect.isEmpty()) + continue; - drawTexture(rect, d_ptr->tex_id, window()->size(), rect); + drawTexture(rect, d_ptr->tex_id, window()->size(), rect); + } } - } #endif + } d_ptr->paintedRegion = QRegion(); context()->swapBuffers(); @@ -422,7 +431,7 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & } QSize size = widget->rect().size(); - if (ctx->format().doubleBuffer()) { + if (d_ptr->destructive_swap_buffers && ctx->format().doubleBuffer()) { rect = parent->rect(); br = rect.translated(wOffset); size = parent->size(); @@ -501,13 +510,16 @@ void QGLWindowSurface::updateGeometry() d_ptr->size = rect.size(); if (d_ptr->ctx) { - glBindTexture(target, d_ptr->tex_id); - glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glBindTexture(target, 0); + if (d_ptr->destructive_swap_buffers) { + glBindTexture(target, d_ptr->tex_id); + glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glBindTexture(target, 0); + } return; } - if ((QGLExtensions::glExtensions & QGLExtensions::FramebufferObject) + if (d_ptr->destructive_swap_buffers + && (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject) #ifdef QT_OPENGL_ES_2 && (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit) #endif @@ -542,7 +554,7 @@ void QGLWindowSurface::updateGeometry() } #if !defined(QT_OPENGL_ES_2) - if (d_ptr->pb || !d_ptr->tried_pb) { + if (d_ptr->destructive_swap_buffers && (d_ptr->pb || !d_ptr->tried_pb)) { d_ptr->tried_pb = true; if (d_ptr->pb) { @@ -590,13 +602,15 @@ void QGLWindowSurface::updateGeometry() QGLContext *ctx = reinterpret_cast(window()->d_func()->extraData()->glContext); ctx->makeCurrent(); - glGenTextures(1, &d_ptr->tex_id); - glBindTexture(target, d_ptr->tex_id); - glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + if (d_ptr->destructive_swap_buffers) { + glGenTextures(1, &d_ptr->tex_id); + glBindTexture(target, d_ptr->tex_id); + glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glBindTexture(target, 0); + glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glBindTexture(target, 0); + } qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;; d_ptr->ctx = ctx; -- cgit v0.12 From 30ed4ee8cee66bcf3ddf001118ba4905a8bfe644 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 25 May 2009 11:24:40 +0200 Subject: Fixed 'crazy' warnings about using a string instead of a character Wherever I found that we were using a string instead of a single char I fixed the code. Reviewed-by: olivier --- src/corelib/global/qglobal.cpp | 4 ++-- src/corelib/io/qdebug.h | 28 +++++++++++++-------------- src/corelib/io/qdir.cpp | 10 +++++----- src/corelib/io/qfsfileengine_win.cpp | 12 +++++------- src/corelib/io/qiodevice.cpp | 2 +- src/corelib/io/qprocess.cpp | 2 +- src/corelib/io/qprocess_win.cpp | 20 +++++++++---------- src/corelib/io/qresource.cpp | 8 ++++---- src/corelib/io/qsettings_win.cpp | 2 +- src/corelib/io/qtemporaryfile.cpp | 2 +- src/corelib/io/qtextstream.cpp | 2 +- src/corelib/io/qurl.cpp | 6 +++--- src/corelib/io/qurl.h | 2 +- src/corelib/kernel/qabstractitemmodel.cpp | 12 ++++++------ src/corelib/kernel/qcoreapplication.cpp | 4 ++-- src/corelib/kernel/qcoreapplication_win.cpp | 4 ++-- src/corelib/kernel/qobject.cpp | 2 +- src/corelib/statemachine/qstatemachine.cpp | 24 +++++++++++------------ src/corelib/tools/qdatetime.cpp | 6 +++--- src/corelib/tools/qline.cpp | 4 ++-- src/corelib/tools/qlocale.cpp | 4 ++-- src/corelib/tools/qpoint.cpp | 2 +- src/gui/dialogs/qfiledialog.cpp | 10 +++++----- src/gui/dialogs/qfiledialog_win.cpp | 18 ++++++++--------- src/gui/dialogs/qfilesystemmodel.cpp | 4 ++-- src/gui/dialogs/qmessagebox.cpp | 2 +- src/gui/dialogs/qprintpreviewdialog.cpp | 2 +- src/gui/graphicsview/qgraphicsitem.cpp | 6 +++--- src/gui/graphicsview/qgraphicsview.cpp | 2 +- src/gui/graphicsview/qgraphicswidget.cpp | 2 +- src/gui/graphicsview/qgridlayoutengine.cpp | 6 +++--- src/gui/image/qxpmhandler.cpp | 6 +++--- src/gui/itemviews/qdirmodel.cpp | 2 +- src/gui/itemviews/qfileiconprovider.cpp | 3 +-- src/gui/itemviews/qitemselectionmodel.cpp | 2 +- src/gui/itemviews/qtableview.cpp | 2 +- src/gui/kernel/qevent.cpp | 6 +++--- src/gui/kernel/qlayoutengine.cpp | 2 +- src/gui/kernel/qmime_win.cpp | 2 +- src/gui/kernel/qshortcutmap.cpp | 4 ++-- src/gui/kernel/qwidget.cpp | 4 ++-- src/gui/painting/qcolor.cpp | 6 +++--- src/gui/painting/qmatrix.cpp | 2 +- src/gui/painting/qpaintengine_raster.cpp | 4 ++-- src/gui/painting/qpaintengineex.cpp | 2 +- src/gui/painting/qpainterpath.cpp | 2 +- src/gui/painting/qpdf.cpp | 26 ++++++++++++------------- src/gui/painting/qpen.cpp | 2 +- src/gui/painting/qprintengine_pdf.cpp | 4 ++-- src/gui/painting/qprintengine_ps.cpp | 24 +++++++++++------------ src/gui/painting/qregion.cpp | 6 +++--- src/gui/painting/qtessellator.cpp | 12 ++++++------ src/gui/painting/qtransform.cpp | 2 +- src/gui/styles/qcleanlooksstyle.cpp | 6 +++--- src/gui/styles/qcommonstyle.cpp | 4 ++-- src/gui/styles/qplastiquestyle.cpp | 4 ++-- src/gui/styles/qstyle.cpp | 2 +- src/gui/styles/qstyleoption.cpp | 8 ++++---- src/gui/styles/qstylesheetstyle.cpp | 2 +- src/gui/text/qcssparser.cpp | 4 ++-- src/gui/text/qfontdatabase.cpp | 4 ++-- src/gui/text/qfontengine.cpp | 2 +- src/gui/text/qfontsubset.cpp | 30 ++++++++++++++--------------- src/gui/text/qtextcontrol.cpp | 2 +- src/gui/text/qtextdocument.cpp | 2 +- src/gui/text/qtextengine.cpp | 2 +- src/gui/util/qcompleter.cpp | 2 +- src/gui/util/qsystemtrayicon_win.cpp | 2 +- src/gui/widgets/qabstractspinbox.cpp | 4 ++-- src/gui/widgets/qcalendarwidget.cpp | 14 +++++++------- src/gui/widgets/qlabel.cpp | 2 +- src/gui/widgets/qlineedit.cpp | 2 +- src/gui/widgets/qspinbox.cpp | 6 +++--- 73 files changed, 220 insertions(+), 223 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index ce98ec4..564e6a5 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1985,7 +1985,7 @@ void qt_message_output(QtMsgType msgType, const char *buf) mac_default_handler(buf); #elif defined(Q_OS_WINCE) QString fstr = QString::fromLatin1(buf); - fstr += QLatin1String("\n"); + fstr += QLatin1Char('\n'); OutputDebugString(reinterpret_cast (fstr.utf16())); #else fprintf(stderr, "%s\n", buf); @@ -2243,7 +2243,7 @@ bool qputenv(const char *varName, const QByteArray& value) return _putenv_s(varName, value.constData()) == 0; #else QByteArray buffer(varName); - buffer += "="; + buffer += '='; buffer += value; return putenv(qstrdup(buffer.constData())) == 0; #endif diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 9b0fbe5..54121f6 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -85,11 +85,11 @@ public: delete stream; } } - inline QDebug &space() { stream->space = true; stream->ts << " "; return *this; } + inline QDebug &space() { stream->space = true; stream->ts << ' '; return *this; } inline QDebug &nospace() { stream->space = false; return *this; } - inline QDebug &maybeSpace() { if (stream->space) stream->ts << " "; return *this; } + inline QDebug &maybeSpace() { if (stream->space) stream->ts << ' '; return *this; } - inline QDebug &operator<<(QChar t) { stream->ts << "\'" << t << "\'"; return maybeSpace(); } + inline QDebug &operator<<(QChar t) { stream->ts << '\'' << t << '\''; return maybeSpace(); } inline QDebug &operator<<(QBool t) { stream->ts << (bool(t) ? "true" : "false"); return maybeSpace(); } inline QDebug &operator<<(bool t) { stream->ts << (t ? "true" : "false"); return maybeSpace(); } inline QDebug &operator<<(char t) { stream->ts << t; return maybeSpace(); } @@ -106,10 +106,10 @@ public: inline QDebug &operator<<(float t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(double t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(const char* t) { stream->ts << QString::fromAscii(t); return maybeSpace(); } - inline QDebug &operator<<(const QString & t) { stream->ts << "\"" << t << "\""; return maybeSpace(); } + inline QDebug &operator<<(const QString & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); } inline QDebug &operator<<(const QStringRef & t) { return operator<<(t.toString()); } - inline QDebug &operator<<(const QLatin1String &t) { stream->ts << "\"" << t.latin1() << "\""; return maybeSpace(); } - inline QDebug &operator<<(const QByteArray & t) { stream->ts << "\"" << t << "\""; return maybeSpace(); } + inline QDebug &operator<<(const QLatin1String &t) { stream->ts << '\"' << t.latin1() << '\"'; return maybeSpace(); } + inline QDebug &operator<<(const QByteArray & t) { stream->ts << '\"' << t << '\"'; return maybeSpace(); } inline QDebug &operator<<(const void * t) { stream->ts << t; return maybeSpace(); } inline QDebug &operator<<(QTextStreamFunction f) { stream->ts << f; @@ -159,13 +159,13 @@ template inline QDebug operator<<(QDebug debug, const QList &list) #endif { - debug.nospace() << "("; + debug.nospace() << '('; for (Q_TYPENAME QList::size_type i = 0; i < list.count(); ++i) { if (i) debug << ", "; debug << list.at(i); } - debug << ")"; + debug << ')'; return debug.space(); } @@ -192,9 +192,9 @@ inline QDebug operator<<(QDebug debug, const QMap &map) debug.nospace() << "QMap("; for (typename QMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it) { - debug << "(" << it.key() << ", " << it.value() << ")"; + debug << '(' << it.key() << ", " << it.value() << ')'; } - debug << ")"; + debug << ')'; return debug.space(); } @@ -209,8 +209,8 @@ inline QDebug operator<<(QDebug debug, const QHash &hash) debug.nospace() << "QHash("; for (typename QHash::const_iterator it = hash.constBegin(); it != hash.constEnd(); ++it) - debug << "(" << it.key() << ", " << it.value() << ")"; - debug << ")"; + debug << '(' << it.key() << ", " << it.value() << ')'; + debug << ')'; return debug.space(); } @@ -222,7 +222,7 @@ template inline QDebug operator<<(QDebug debug, const QPair &pair) #endif { - debug.nospace() << "QPair(" << pair.first << "," << pair.second << ")"; + debug.nospace() << "QPair(" << pair.first << ',' << pair.second << ')'; return debug.space(); } @@ -247,7 +247,7 @@ inline QDebug operator<<(QDebug debug, const QContiguousCache &cache) if (i != cache.lastIndex()) debug << ", "; } - debug << ")"; + debug << ')'; return debug.space(); } diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 0dc8a63..7d330e6 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -2417,7 +2417,7 @@ QDebug operator<<(QDebug debug, QDir::Filters filters) if (filters & QDir::System) flags << QLatin1String("System"); if (filters & QDir::CaseSensitive) flags << QLatin1String("CaseSensitive"); } - debug << "QDir::Filters(" << qPrintable(flags.join(QLatin1String("|"))) << ")"; + debug << "QDir::Filters(" << qPrintable(flags.join(QLatin1String("|"))) << ')'; return debug; } @@ -2439,8 +2439,8 @@ QDebug operator<<(QDebug debug, QDir::SortFlags sorting) if (sorting & QDir::LocaleAware) flags << QLatin1String("LocaleAware"); if (sorting & QDir::Type) flags << QLatin1String("Type"); debug << "QDir::SortFlags(" << qPrintable(type) - << "|" - << qPrintable(flags.join(QLatin1String("|"))) << ")"; + << '|' + << qPrintable(flags.join(QLatin1String("|"))) << ')'; } return debug; } @@ -2452,9 +2452,9 @@ QDebug operator<<(QDebug debug, const QDir &dir) << qPrintable(dir.nameFilters().join(QLatin1String(","))) << "}, " << dir.sorting() - << "," + << ',' << dir.filter() - << ")"; + << ')'; return debug.space(); } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 5d6cd06..aee9fde 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -433,7 +433,7 @@ static QString nativeAbsoluteFilePathW(const QString &path) if (retLen != 0) ret = QString::fromUtf16((unsigned short *)buf.data(), retLen); #else - if (path.startsWith(QLatin1String("/")) || path.startsWith(QLatin1String("\\"))) + if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\'))) ret = QDir::toNativeSeparators(path); else ret = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path)); @@ -1240,7 +1240,7 @@ QString QFSFileEngine::rootPath() QString ret = QString::fromLatin1(qgetenv("SystemDrive").constData()); if(ret.isEmpty()) ret = QLatin1String("c:"); - ret += QLatin1String("/"); + ret += QLatin1Char('/'); #elif defined(Q_OS_OS2EMX) char dir[4]; _abspath(dir, QLatin1String("/"), _MAX_PATH); @@ -1288,19 +1288,17 @@ QFileInfoList QFSFileEngine::drives() exit(1); driveBits &= 0x3ffffff; #endif - char driveName[4]; - - qstrcpy(driveName, "A:/"); + char driveName[] = "A:/"; while(driveBits) { if(driveBits & 1) - ret.append(QString::fromLatin1(driveName).toUpper()); + ret.append(QString::fromLatin1(driveName)); driveName[0]++; driveBits = driveBits >> 1; } return ret; #else - ret.append(QString::fromLatin1("/").toUpper()); + ret.append(QLatin1Char('/')); return ret; #endif } diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 2ccc6ea..8924b77 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -1745,7 +1745,7 @@ QDebug operator<<(QDebug debug, QIODevice::OpenMode modes) } qSort(modeList); debug << modeList.join(QLatin1String("|")); - debug << ")"; + debug << ')'; return debug; } #endif diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 30f4291..afeaad6 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1586,7 +1586,7 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM } #if defined QPROCESS_DEBUG - qDebug() << "QProcess::start(" << program << "," << arguments << "," << mode << ")"; + qDebug() << "QProcess::start(" << program << ',' << arguments << ',' << mode << ')'; #endif d->outputReadBuffer.clear(); diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 5d862e5..179c3d0 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -272,12 +272,12 @@ static QString qt_create_commandline(const QString &program, const QStringList & QString args; if (!program.isEmpty()) { QString programName = program; - if (!programName.startsWith(QLatin1Char('\"')) && !programName.endsWith(QLatin1Char('\"')) && programName.contains(QLatin1String(" "))) - programName = QLatin1String("\"") + programName + QLatin1String("\""); - programName.replace(QLatin1String("/"), QLatin1String("\\")); + if (!programName.startsWith(QLatin1Char('\"')) && !programName.endsWith(QLatin1Char('\"')) && programName.contains(QLatin1Char(' '))) + programName = QLatin1Char('\"') + programName + QLatin1Char('\"'); + programName.replace(QLatin1Char('/'), QLatin1Char('\\')); // add the prgram as the first arg ... it works better - args = programName + QLatin1String(" "); + args = programName + QLatin1Char(' '); } for (int i=0; i0 && tmp.at(i-1) == QLatin1Char('\\')) { --i; - endQuote += QLatin1String("\\"); + endQuote += QLatin1Char('\\'); } args += QLatin1String(" \"") + tmp.left(i) + endQuote; } else { @@ -427,7 +427,7 @@ void QProcessPrivate::startProcess() QString fullPathProgram = program; if (!QDir::isAbsolutePath(fullPathProgram)) fullPathProgram = QFileInfo(fullPathProgram).absoluteFilePath(); - fullPathProgram.replace(QLatin1String("/"), QLatin1String("\\")); + fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\')); success = CreateProcessW((WCHAR*)fullPathProgram.utf16(), (WCHAR*)args.utf16(), 0, 0, false, 0, 0, 0, 0, pid); @@ -887,8 +887,8 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a #if defined(Q_OS_WINCE) QString fullPathProgram = program; if (!QDir::isAbsolutePath(fullPathProgram)) - fullPathProgram.prepend(QDir::currentPath().append(QLatin1String("/"))); - fullPathProgram.replace(QLatin1String("/"), QLatin1String("\\")); + fullPathProgram.prepend(QDir::currentPath().append(QLatin1Char('/'))); + fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\')); success = CreateProcessW((WCHAR*)fullPathProgram.utf16(), (WCHAR*)args.utf16(), 0, 0, false, CREATE_NEW_CONSOLE, 0, 0, 0, &pinfo); diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 3b704f6..94dfd4d 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -623,14 +623,14 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const QString root = mappingRoot(); if(!root.isEmpty()) { if(root == path) { - path = QLatin1String("/"); + path = QLatin1Char('/'); } else { - if(!root.endsWith(QLatin1String("/"))) - root += QLatin1String("/"); + if(!root.endsWith(QLatin1Char('/'))) + root += QLatin1Char('/'); if(path.size() >= root.size() && path.startsWith(root)) path = path.mid(root.length()-1); if(path.isEmpty()) - path = QLatin1String("/"); + path = QLatin1Char('/'); } } } diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp index a08c969..57f65d6 100644 --- a/src/corelib/io/qsettings_win.cpp +++ b/src/corelib/io/qsettings_win.cpp @@ -148,7 +148,7 @@ static QString errorCodeToString(DWORD errorCode) if (data != 0) LocalFree(data); }) - if (result.endsWith(QLatin1String("\n"))) + if (result.endsWith(QLatin1Char('\n'))) result.truncate(result.length() - 1); return result; diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index b4d8a48..728bf4f 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -203,7 +203,7 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) if (QDir::isAbsolutePath(QString::fromLatin1(path))) targetPath = QLatin1String(path); else - targetPath = QDir::currentPath().append(QLatin1String("/")) + QLatin1String(path); + targetPath = QDir::currentPath().append(QLatin1Char('/')) + QLatin1String(path); if ((*doopen = QT_OPEN(targetPath.toLocal8Bit(), O_CREAT|O_EXCL|O_RDWR diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 612d7f7..4563e84 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -2292,7 +2292,7 @@ bool QTextStreamPrivate::putNumber(qulonglong number, bool negative) // ShowBase flag set zero should be written as '00' if (number == 0 && base == 8 && numberFlags & QTextStream::ShowBase && result == QLatin1String("0")) { - result.prepend(QLatin1String("0")); + result.prepend(QLatin1Char('0')); } } return putString(result, true); diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index d1a5cdd..94a53f1 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -5698,7 +5698,7 @@ QUrl QUrl::fromLocalFile(const QString &localFile) // magic for drives on windows if (deslashified.length() > 1 && deslashified.at(1) == QLatin1Char(':') && deslashified.at(0) != QLatin1Char('/')) { - url.setPath(QLatin1String("/") + deslashified); + url.setPath(QLatin1Char('/') + deslashified); // magic for shared drive on windows } else if (deslashified.startsWith(QLatin1String("//"))) { int indexOfPath = deslashified.indexOf(QLatin1Char('/'), 2); @@ -5728,7 +5728,7 @@ QString QUrl::toLocalFile() const // magic for shared drive on windows if (!d->host.isEmpty()) { tmp = QLatin1String("//") + d->host + (ourPath.length() > 0 && ourPath.at(0) != QLatin1Char('/') - ? QLatin1String("/") + ourPath : ourPath); + ? QLatin1Char('/') + ourPath : ourPath); } else { tmp = ourPath; // magic for drives on windows @@ -5976,7 +5976,7 @@ QDataStream &operator>>(QDataStream &in, QUrl &url) #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QUrl &url) { - d.maybeSpace() << "QUrl(" << url.toString() << ")"; + d.maybeSpace() << "QUrl(" << url.toString() << ')'; return d.space(); } #endif diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h index 9242092..e9c4a8d 100644 --- a/src/corelib/io/qurl.h +++ b/src/corelib/io/qurl.h @@ -223,7 +223,7 @@ public: inline QT3_SUPPORT QString ref() const { return fragment(); } inline QT3_SUPPORT void setRef(const QString &txt) { setFragment(txt); } inline QT3_SUPPORT bool hasRef() const { return !fragment().isEmpty(); } - inline QT3_SUPPORT void addPath(const QString &p) { setPath(path() + QLatin1String("/") + p); } + inline QT3_SUPPORT void addPath(const QString &p) { setPath(path() + QLatin1Char('/') + p); } QT3_SUPPORT void setFileName(const QString &txt); QT3_SUPPORT QString fileName() const; QT3_SUPPORT QString dirPath() const; diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index fd0e105..935c0aa 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -428,8 +428,8 @@ bool QPersistentModelIndex::isValid() const QDebug operator<<(QDebug dbg, const QModelIndex &idx) { #ifndef Q_BROKEN_DEBUG_STREAM - dbg.nospace() << "QModelIndex(" << idx.row() << "," << idx.column() - << "," << idx.internalPointer() << "," << idx.model() << ")"; + dbg.nospace() << "QModelIndex(" << idx.row() << ',' << idx.column() + << ',' << idx.internalPointer() << ',' << idx.model() << ')'; return dbg.space(); #else qWarning("This compiler doesn't support streaming QModelIndex to QDebug"); @@ -525,7 +525,7 @@ void QAbstractItemModelPrivate::rowsInserted(const QModelIndex &parent, if (data->index.isValid()) { persistent.insertMultiAtEnd(data->index, data); } else { - qWarning() << "QAbstractItemModel::endInsertRows: Invalid index (" << old.row() + count << "," << old.column() << ") in model" << q_func(); + qWarning() << "QAbstractItemModel::endInsertRows: Invalid index (" << old.row() + count << ',' << old.column() << ") in model" << q_func(); } } } @@ -574,7 +574,7 @@ void QAbstractItemModelPrivate::rowsRemoved(const QModelIndex &parent, if (data->index.isValid()) { persistent.insertMultiAtEnd(data->index, data); } else { - qWarning() << "QAbstractItemModel::endRemoveRows: Invalid index (" << old.row() - count << "," << old.column() << ") in model" << q_func(); + qWarning() << "QAbstractItemModel::endRemoveRows: Invalid index (" << old.row() - count << ',' << old.column() << ") in model" << q_func(); } } QVector persistent_invalidated = persistent.invalidated.pop(); @@ -619,7 +619,7 @@ void QAbstractItemModelPrivate::columnsInserted(const QModelIndex &parent, if (data->index.isValid()) { persistent.insertMultiAtEnd(data->index, data); } else { - qWarning() << "QAbstractItemModel::endInsertColumns: Invalid index (" << old.row() << "," << old.column() + count << ") in model" << q_func(); + qWarning() << "QAbstractItemModel::endInsertColumns: Invalid index (" << old.row() << ',' << old.column() + count << ") in model" << q_func(); } } } @@ -669,7 +669,7 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent, if (data->index.isValid()) { persistent.insertMultiAtEnd(data->index, data); } else { - qWarning() << "QAbstractItemModel::endRemoveColumns: Invalid index (" << old.row() << "," << old.column() - count << ") in model" << q_func(); + qWarning() << "QAbstractItemModel::endRemoveColumns: Invalid index (" << old.row() << ',' << old.column() - count << ") in model" << q_func(); } } QVector persistent_invalidated = persistent.invalidated.pop(); diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 77ef096..6847173 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1798,7 +1798,7 @@ QString QCoreApplication::applicationFilePath() */ QByteArray pEnv = qgetenv("PATH"); QDir currentDir = QDir::current(); - QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1String(":")); + QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1Char(':')); for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) { if ((*p).isEmpty()) continue; @@ -1908,7 +1908,7 @@ QStringList QCoreApplication::arguments() wchar_t tempFilename[MAX_PATH+1]; if (GetModuleFileNameW(0, tempFilename, MAX_PATH)) { tempFilename[MAX_PATH] = 0; - cmdline.prepend(QString(QLatin1String("\"")) + QString::fromUtf16((unsigned short *)tempFilename) + QString(QLatin1String("\" "))); + cmdline.prepend(QLatin1Char('\"') + QString::fromUtf16((unsigned short *)tempFilename) + QString(QLatin1String("\" "))); } #endif // Q_OS_WINCE diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 225821f..7ab91c9 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -134,11 +134,11 @@ Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str) staticCriticalSection.lock(); QT_WA({ QString s(QString::fromLocal8Bit(str)); - s += QLatin1String("\n"); + s += QLatin1Char('\n'); OutputDebugStringW((TCHAR*)s.utf16()); }, { QByteArray s(str); - s += "\n"; + s += '\n'; OutputDebugStringA(s.data()); }) staticCriticalSection.unlock(); diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1e9e284..65d81f1 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3461,7 +3461,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) { #ifndef Q_BROKEN_DEBUG_STREAM if (!o) return dbg << "QObject(0x0) "; - dbg.nospace() << o->metaObject()->className() << "(" << (void *)o; + dbg.nospace() << o->metaObject()->className() << '(' << (void *)o; if (!o->objectName().isEmpty()) dbg << ", name = " << o->objectName(); dbg << ')'; diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 744515b..309c8be 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -354,7 +354,7 @@ bool QStateMachinePrivate::isPreempted(const QAbstractState *s, const QSet QStateMachinePrivate::selectTransitions(QEvent *event void QStateMachinePrivate::microstep(QEvent *event, const QList &enabledTransitions) { #ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": begin microstep( enabledTransitions:" << enabledTransitions << ")"; + qDebug() << q_func() << ": begin microstep( enabledTransitions:" << enabledTransitions << ')'; qDebug() << q_func() << ": configuration before exiting states:" << configuration; #endif QList exitedStates = exitStates(event, enabledTransitions); @@ -421,7 +421,7 @@ void QStateMachinePrivate::microstep(QEvent *event, const QList QStateMachinePrivate::exitStates(QEvent *event, const QList &enabledTransitions) { -// qDebug() << "exitStates(" << enabledTransitions << ")"; +// qDebug() << "exitStates(" << enabledTransitions << ')'; QSet statesToExit; // QSet statesToSnapshot; for (int i = 0; i < enabledTransitions.size(); ++i) { @@ -470,7 +470,7 @@ QList QStateMachinePrivate::exitStates(QEvent *event, const QLi } #ifdef QSTATEMACHINE_DEBUG qDebug() << q_func() << ": recorded" << ((QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) ? "deep" : "shallow") - << "history for" << s << "in" << h << ":" << QHistoryStatePrivate::get(h)->configuration; + << "history for" << s << "in" << h << ':' << QHistoryStatePrivate::get(h)->configuration; #endif } } @@ -503,7 +503,7 @@ QList QStateMachinePrivate::enterStates(QEvent *event, const QL #ifdef QSTATEMACHINE_DEBUG Q_Q(QStateMachine); #endif -// qDebug() << "enterStates(" << enabledTransitions << ")"; +// qDebug() << "enterStates(" << enabledTransitions << ')'; QSet statesToEnter; QSet statesForDefaultEntry; @@ -609,7 +609,7 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, #ifdef QSTATEMACHINE_DEBUG qDebug() <historyType == QHistoryState::DeepHistory) ? "deep" : "shallow") - << "history from" << s << ":" << hconf; + << "history from" << s << ':' << hconf; #endif } else { QList hlst; @@ -624,7 +624,7 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry); } #ifdef QSTATEMACHINE_DEBUG - qDebug() << q_func() << ": initial history targets for" << s << ":" << hlst; + qDebug() << q_func() << ": initial history targets for" << s << ':' << hlst; #endif } } @@ -968,7 +968,7 @@ QVariant QStateMachinePrivate::restorableValue(QObject *object, const QByteArray */ void QStateMachinePrivate::unregisterRestorable(QObject *object, const QByteArray &propertyName) { -// qDebug() << "unregisterRestorable(" << object << propertyName << ")"; +// qDebug() << "unregisterRestorable(" << object << propertyName << ')'; RestorableId id(object, propertyName); registeredRestorables.remove(id); } @@ -1341,7 +1341,7 @@ void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transitio #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": FAILED to add signal transition from" << transition->sourceState() << ": ( sender =" << sender << ", signal =" << (signal.mid(1)) - << ", targets =" << transition->targetStates() << ")"; + << ", targets =" << transition->targetStates() << ')'; #endif return; } @@ -1351,7 +1351,7 @@ void QStateMachinePrivate::registerSignalTransition(QSignalTransition *transitio #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": added signal transition from" << transition->sourceState() << ": ( sender =" << sender << ", signal =" << (signal.mid(1)) - << ", targets =" << transition->targetStates() << ")"; + << ", targets =" << transition->targetStates() << ')'; #endif } @@ -1412,7 +1412,7 @@ void QStateMachinePrivate::registerEventTransition(QEventTransition *transition) #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": added event transition from" << transition->sourceState() << ": ( object =" << object << ", event =" << transition->eventType() - << ", targets =" << transition->targetStates() << ")"; + << ", targets =" << transition->targetStates() << ')'; #endif } @@ -1456,7 +1456,7 @@ void QStateMachinePrivate::handleTransitionSignal(const QObject *sender, int sig #ifdef QSTATEMACHINE_DEBUG qDebug() << q_func() << ": sending signal event ( sender =" << sender - << ", signal =" << sender->metaObject()->method(signalIndex).signature() << ")"; + << ", signal =" << sender->metaObject()->method(signalIndex).signature() << ')'; #endif internalEventQueue.append(new QSignalEvent(sender, signalIndex, vargs)); scheduleProcess(); diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 781514c..090ca61 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -3833,19 +3833,19 @@ void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING) QDebug operator<<(QDebug dbg, const QDate &date) { - dbg.nospace() << "QDate(" << date.toString() << ")"; + dbg.nospace() << "QDate(" << date.toString() << ')'; return dbg.space(); } QDebug operator<<(QDebug dbg, const QTime &time) { - dbg.nospace() << "QTime(" << time.toString() << ")"; + dbg.nospace() << "QTime(" << time.toString() << ')'; return dbg.space(); } QDebug operator<<(QDebug dbg, const QDateTime &date) { - dbg.nospace() << "QDateTime(" << date.toString() << ")"; + dbg.nospace() << "QDateTime(" << date.toString() << ')'; return dbg.space(); } #endif diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index f615dcd..88825a3 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -260,7 +260,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QLine &p) { - d << "QLine(" << p.p1() << "," << p.p2() << ")"; + d << "QLine(" << p.p1() << ',' << p.p2() << ')'; return d; } #endif @@ -822,7 +822,7 @@ qreal QLineF::angle(const QLineF &l) const #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QLineF &p) { - d << "QLineF(" << p.p1() << "," << p.p2() << ")"; + d << "QLineF(" << p.p1() << ',' << p.p2() << ')'; return d; } #endif diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 66e3921..23c6ffb 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1136,7 +1136,7 @@ static QString macToQtFormat(const QString &sys_fmt) break; case 'S': // fractional second if (repeat < 3) - result += QLatin1String("z"); + result += QLatin1Char('z'); else result += QLatin1String("zzz"); break; @@ -1150,7 +1150,7 @@ static QString macToQtFormat(const QString &sys_fmt) if (repeat >= 2) result += QLatin1String("dd"); else - result += QLatin1String("d"); + result += QLatin1Char('d'); break; case 'a': result += QLatin1String("AP"); diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp index 5cc71d6..90b44b1 100644 --- a/src/corelib/tools/qpoint.cpp +++ b/src/corelib/tools/qpoint.cpp @@ -373,7 +373,7 @@ QDebug operator<<(QDebug dbg, const QPoint &p) { QDebug operator<<(QDebug d, const QPointF &p) { - d.nospace() << "QPointF(" << p.x() << ", " << p.y() << ")"; + d.nospace() << "QPointF(" << p.x() << ", " << p.y() << ')'; return d; } #endif diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 903cd74..3ccae3a 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -837,8 +837,8 @@ QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList filesT // This check is needed since we might be at the root directory // and on Windows it already ends with slash. QString path = rootPath(); - if (!path.endsWith(QLatin1String("/"))) - path += QLatin1String("/"); + if (!path.endsWith(QLatin1Char('/'))) + path += QLatin1Char('/'); path += name; files.append(path); } @@ -2649,7 +2649,7 @@ void QFileDialogPrivate::_q_deleteCurrent() void QFileDialogPrivate::_q_autoCompleteFileName(const QString &text) { - if (text.startsWith(QLatin1String("//")) || text.startsWith(QLatin1String("\\"))) { + if (text.startsWith(QLatin1String("//")) || text.startsWith(QLatin1Char('\\'))) { qFileDialogUi->listView->selectionModel()->clearSelection(); return; } @@ -2691,7 +2691,7 @@ void QFileDialogPrivate::_q_updateOkButton() QStringList files = q->selectedFiles(); QString lineEditText = lineEdit()->text(); - if (lineEditText.startsWith(QLatin1String("//")) || lineEditText.startsWith(QLatin1String("\\"))) { + if (lineEditText.startsWith(QLatin1String("//")) || lineEditText.startsWith(QLatin1Char('\\'))) { button->setEnabled(true); if (acceptMode == QFileDialog::AcceptSave) button->setText(isOpenDirectory ? QFileDialog::tr("&Open") : acceptLabel); @@ -3197,7 +3197,7 @@ QStringList QFSCompletor::splitPath(const QString &path) const doubleSlash.clear(); #endif - QRegExp re(QLatin1String("[") + QRegExp::escape(sep) + QLatin1String("]")); + QRegExp re(QLatin1Char('[') + QRegExp::escape(sep) + QLatin1Char(']')); #ifdef Q_OS_WIN QStringList parts = pathCopy.split(re, QString::SkipEmptyParts); diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index 6962674..75a1820 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -214,10 +214,10 @@ static OPENFILENAMEA *qt_win_make_OFNA(QWidget *parent, aInitSel = ""; } else { aInitSel = QDir::toNativeSeparators(initialSelection).toLocal8Bit(); - aInitSel.replace("<", ""); - aInitSel.replace(">", ""); - aInitSel.replace("\"", ""); - aInitSel.replace("|", ""); + aInitSel.replace('<', ""); + aInitSel.replace('>', ""); + aInitSel.replace('\"', ""); + aInitSel.replace('|', ""); } int maxLen = mode == QFileDialog::ExistingFiles ? maxMultiLen : maxNameLen; aInitSel.resize(maxLen + 1); // make room for return value @@ -286,10 +286,10 @@ static OPENFILENAME* qt_win_make_OFN(QWidget *parent, tTitle = title; QString initSel = QDir::toNativeSeparators(initialSelection); if (!initSel.isEmpty()) { - initSel.replace(QLatin1String("<"), QLatin1String("")); - initSel.replace(QLatin1String(">"), QLatin1String("")); - initSel.replace(QLatin1String("\""), QLatin1String("")); - initSel.replace(QLatin1String("|"), QLatin1String("")); + initSel.remove(QLatin1Char('<')); + initSel.remove(QLatin1Char('>')); + initSel.remove(QLatin1Char('\"')); + initSel.remove(QLatin1Char('|')); } int maxLen = mode == QFileDialog::ExistingFiles ? maxMultiLen : maxNameLen; @@ -811,7 +811,7 @@ QString qt_win_get_existing_directory(const QFileDialogArgs &args) QDir::setCurrent(currentDir); if (!result.isEmpty()) - result.replace(QLatin1String("\\"), QLatin1String("/")); + result.replace(QLatin1Char('\\'), QLatin1Char('/')); return result; } diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index 012d3a1..eeca9f9 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -337,7 +337,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS { Q_Q(const QFileSystemModel); Q_UNUSED(q); - if (path.isEmpty() || path == myComputer() || path.startsWith(QLatin1String(":"))) + if (path.isEmpty() || path == myComputer() || path.startsWith(QLatin1Char(':'))) return const_cast(&root); // Construct the nodes up to the new root path if they need to be built @@ -356,7 +356,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS QStringList pathElements = absolutePath.split(QLatin1Char('/'), QString::SkipEmptyParts); if ((pathElements.isEmpty()) #if !defined(Q_OS_WIN) || defined(Q_OS_WINCE) - && QDir::fromNativeSeparators(longPath) != QLatin1String("/") + && QDir::fromNativeSeparators(longPath) != QLatin1Char('/') #endif ) return const_cast(&root); diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index 533c538..ae5b4a3 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -1310,7 +1310,7 @@ void QMessageBox::keyPressEvent(QKeyEvent *e) if (e == QKeySequence::Copy) { QString separator = QString::fromLatin1("---------------------------\n"); QString textToCopy = separator; - separator.prepend(QLatin1String("\n")); + separator.prepend(QLatin1Char('\n')); textToCopy += windowTitle() + separator; // title textToCopy += d->label->text() + separator; // text diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp index 3580fdc..29a2738 100644 --- a/src/gui/dialogs/qprintpreviewdialog.cpp +++ b/src/gui/dialogs/qprintpreviewdialog.cpp @@ -558,7 +558,7 @@ void QPrintPreviewDialogPrivate::_q_print() suffix = QLatin1String(".ps"); } QString fileName = QFileDialog::getSaveFileName(q, title, printer->outputFileName(), - QLatin1String("*") + suffix); + QLatin1Char('*') + suffix); if (!fileName.isEmpty()) { if (QFileInfo(fileName).suffix().isEmpty()) fileName.append(suffix); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index bd764b5..0398fac 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -9588,17 +9588,17 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag) QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags) { - debug << "("; + debug << '('; bool f = false; for (int i = 0; i < 9; ++i) { if (flags & (1 << i)) { if (f) - debug << "|"; + debug << '|'; f = true; debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i))); } } - debug << ")"; + debug << ')'; return debug; } diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 396618c..501aef1 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -3389,7 +3389,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event) #ifdef QGRAPHICSVIEW_DEBUG QTime stopWatch; stopWatch.start(); - qDebug() << "QGraphicsView::paintEvent(" << exposedRegion << ")"; + qDebug() << "QGraphicsView::paintEvent(" << exposedRegion << ')'; #endif // Find all exposed items diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 702e0b6..a2e55e1 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -2295,7 +2295,7 @@ void QGraphicsWidget::dumpFocusChain() qWarning("Found a focus chain that is not circular, (next == 0)"); break; } - qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromAscii("focusItem:%1").arg(next->hasFocus() ? "1" : "0") << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0); + qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromAscii("focusItem:%1").arg(next->hasFocus() ? '1' : '0') << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0); if (visited.contains(next)) { qWarning("Already visited this node. However, I expected to dump until I found myself."); break; diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp index c150b0e..88712c2 100644 --- a/src/gui/graphicsview/qgridlayoutengine.cpp +++ b/src/gui/graphicsview/qgridlayoutengine.cpp @@ -1131,9 +1131,9 @@ void QGridLayoutEngine::dump(int indent) const QString message = QLatin1String("[ "); for (int column = 0; column < internalGridColumnCount(); ++column) { message += QString::number(q_items.indexOf(itemAt(row, column))).rightJustified(3); - message += QLatin1String(" "); + message += QLatin1Char(' '); } - message += QLatin1String("]"); + message += QLatin1Char(']'); qDebug("%*s %s", indent, "", qPrintable(message)); } @@ -1157,7 +1157,7 @@ void QGridLayoutEngine::dump(int indent) const message += QLatin1String((message.isEmpty() ? "[" : ", ")); message += QString::number(cellPos->at(i)); } - message += QLatin1String("]"); + message += QLatin1Char(']'); qDebug("%*s %s %s", indent, "", (pass == 0 ? "rows:" : "columns:"), qPrintable(message)); cellPos = &q_xx; } diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp index 90bd2ab..f4062ad 100644 --- a/src/gui/image/qxpmhandler.cpp +++ b/src/gui/image/qxpmhandler.cpp @@ -1146,7 +1146,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const QTextStream s(device); s << "/* XPM */" << endl << "static char *" << fbname(fileName) << "[]={" << endl - << "\"" << w << " " << h << " " << ncolors << " " << cpp << "\""; + << '\"' << w << ' ' << h << ' ' << ncolors << ' ' << cpp << '\"'; // write palette QMap::Iterator c = colorMap.begin(); @@ -1162,7 +1162,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const qGreen(color), qBlue(color)); ++c; - s << "," << endl << line; + s << ',' << endl << line; } // write pixels, limit to 4 characters per pixel @@ -1184,7 +1184,7 @@ static bool write_xpm_image(const QImage &sourceImage, QIODevice *device, const } } } - s << "," << endl << "\"" << line << "\""; + s << ',' << endl << '\"' << line << '\"'; } s << "};" << endl; return (s.status() == QTextStream::Ok); diff --git a/src/gui/itemviews/qdirmodel.cpp b/src/gui/itemviews/qdirmodel.cpp index 65e3032..5cd16c0 100644 --- a/src/gui/itemviews/qdirmodel.cpp +++ b/src/gui/itemviews/qdirmodel.cpp @@ -885,7 +885,7 @@ QModelIndex QDirModel::index(const QString &path, int column) const QStringList pathElements = absolutePath.split(QLatin1Char('/'), QString::SkipEmptyParts); if ((pathElements.isEmpty() || !QFileInfo(path).exists()) #if !defined(Q_OS_WIN) || defined(Q_OS_WINCE) - && path != QLatin1String("/") + && path != QLatin1Char('/') #endif ) return QModelIndex(); diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp index 054f4cf..434bcde 100644 --- a/src/gui/itemviews/qfileiconprovider.cpp +++ b/src/gui/itemviews/qfileiconprovider.cpp @@ -215,8 +215,7 @@ QIcon QFileIconProvider::icon(IconType type) const QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const { QIcon retIcon; - QString fileExtension = fileInfo.suffix().toUpper(); - fileExtension.prepend( QLatin1String(".") ); + const QString fileExtension = QLatin1Char('.') + fileInfo.suffix().toUpper(); QString key; if (fileInfo.isFile() && !fileInfo.isExecutable() && !fileInfo.isSymLink()) diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index 8baefdf..696b8fa 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -1553,7 +1553,7 @@ QDebug operator<<(QDebug dbg, const QItemSelectionRange &range) { #ifndef Q_BROKEN_DEBUG_STREAM dbg.nospace() << "QItemSelectionRange(" << range.topLeft() - << "," << range.bottomRight() << ")"; + << ',' << range.bottomRight() << ')'; return dbg.space(); #else qWarning("This compiler doesn't support streaming QItemSelectionRange to QDebug"); diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 757ecf2..0bded54 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -282,7 +282,7 @@ void QTableViewPrivate::trimHiddenSelections(QItemSelectionRange *range) const void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan) { if (row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0) { - qWarning() << "QTableView::setSpan: invalid span given: (" << row << "," << column << "," << rowSpan << "," << columnSpan << ")"; + qWarning() << "QTableView::setSpan: invalid span given: (" << row << ',' << column << ',' << rowSpan << ',' << columnSpan << ')'; return; } QSpanCollection::Span *sp = spans.spanAt(column, row); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 0ab4423..a59e870 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3081,7 +3081,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { << ", " << me->button() << ", " << hex << (int)me->buttons() << ", " << hex << (int)me->modifiers() - << ")"; + << ')'; } return dbg.space(); @@ -3102,7 +3102,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: dbg.nospace() << "QWheelEvent(" << static_cast(e)->delta() - << ")"; + << ')'; return dbg.space(); #endif case QEvent::KeyPress: @@ -3128,7 +3128,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { << ", \"" << ke->text() << "\", " << ke->isAutoRepeat() << ", " << ke->count() - << ")"; + << ')'; } return dbg.space(); case QEvent::FocusIn: diff --git a/src/gui/kernel/qlayoutengine.cpp b/src/gui/kernel/qlayoutengine.cpp index fbaa388..3673f08 100644 --- a/src/gui/kernel/qlayoutengine.cpp +++ b/src/gui/kernel/qlayoutengine.cpp @@ -329,7 +329,7 @@ void qGeomCalc(QVector &chain, int start, int count, qDebug() << "qGeomCalc" << "start" << start << "count" << count << "pos" << pos << "space" << space << "spacer" << spacer; for (i = start; i < start + count; ++i) { - qDebug() << i << ":" << chain[i].minimumSize << chain[i].smartSizeHint() + qDebug() << i << ':' << chain[i].minimumSize << chain[i].smartSizeHint() << chain[i].maximumSize << "stretch" << chain[i].stretch << "empty" << chain[i].empty << "expansive" << chain[i].expansive << "spacing" << chain[i].spacing; diff --git a/src/gui/kernel/qmime_win.cpp b/src/gui/kernel/qmime_win.cpp index cd0aae6..109ce20 100644 --- a/src/gui/kernel/qmime_win.cpp +++ b/src/gui/kernel/qmime_win.cpp @@ -852,7 +852,7 @@ QVariant QWindowsMimeHtml::convertToMime(const QString &mime, IDataObject *pData if (end > start && start > 0) { html = "" + html.mid(start, end - start); html += ""; - html.replace("\r", ""); + html.replace('\r', ""); result = QString::fromUtf8(html); } } diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index f998bb2..3c2fcdd 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -109,7 +109,7 @@ QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) { dbg.nospace() << "QShortcutEntry(" << se->keyseq << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat - << "), owner(" << se->owner << ")"; + << "), owner(" << se->owner << ')'; return dbg.space(); } #endif // QT_NO_DEBUGSTREAM @@ -876,7 +876,7 @@ void QShortcutMap::dispatchEvent(QKeyEvent *e) qDebug().nospace() << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\"" << (QString)next->keyseq << "\", " << next->id << ", " - << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ")"; + << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')'; #endif QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1); QApplication::sendEvent(const_cast(next->owner), &se); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e186557..d6e5cce 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -5236,7 +5236,7 @@ static QString constructWindowTitleFromFilePath(const QString &filePath) #ifndef Q_WS_MAC QString appName = QApplication::applicationName(); if (!appName.isEmpty()) - windowTitle += QLatin1String(" ") + QChar(0x2014) + QLatin1String(" ") + appName; + windowTitle += QLatin1Char(' ') + QChar(0x2014) + QLatin1Char(' ') + appName; #endif return windowTitle; } @@ -5300,7 +5300,7 @@ QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widg && widget->style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, widget)) cap.replace(lastIndex, 3, QWidget::tr("*")); else - cap.replace(lastIndex, 3, QLatin1String("")); + cap.remove(lastIndex, 3); } index = cap.indexOf(placeHolder, index); diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 534a425..6b58f14 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -2022,12 +2022,12 @@ QDebug operator<<(QDebug dbg, const QColor &c) if (!c.isValid()) dbg.nospace() << "QColor(Invalid)"; else if (c.spec() == QColor::Rgb) - dbg.nospace() << "QColor(ARGB " << c.alphaF() << ", " << c.redF() << ", " << c.greenF() << ", " << c.blueF() << ")"; + dbg.nospace() << "QColor(ARGB " << c.alphaF() << ", " << c.redF() << ", " << c.greenF() << ", " << c.blueF() << ')'; else if (c.spec() == QColor::Hsv) - dbg.nospace() << "QColor(AHSV " << c.alphaF() << ", " << c.hueF() << ", " << c.saturationF() << ", " << c.valueF() << ")"; + dbg.nospace() << "QColor(AHSV " << c.alphaF() << ", " << c.hueF() << ", " << c.saturationF() << ", " << c.valueF() << ')'; else if (c.spec() == QColor::Cmyk) dbg.nospace() << "QColor(ACMYK " << c.alphaF() << ", " << c.cyanF() << ", " << c.magentaF() << ", " << c.yellowF() << ", " - << c.blackF()<< ")"; + << c.blackF()<< ')'; return dbg.space(); #else diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp index 31abcad..030415d 100644 --- a/src/gui/painting/qmatrix.cpp +++ b/src/gui/painting/qmatrix.cpp @@ -1178,7 +1178,7 @@ QDebug operator<<(QDebug dbg, const QMatrix &m) << " 22=" << m.m22() << " dx=" << m.dx() << " dy=" << m.dy() - << ")"; + << ')'; return dbg.space(); } #endif diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 0e8f50a..069f73d 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1202,12 +1202,12 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) if (path.elements()) { for (int i=0; i " << types[p.elementAt(i).type] << "(x=" << p.elementAt(i).x << ", y=" << p.elementAt(i).y << ")" << endl; + s.nospace() << " -> " << types[p.elementAt(i).type] << "(x=" << p.elementAt(i).x << ", y=" << p.elementAt(i).y << ')' << endl; } return s; diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 55006f6..0b2db8c 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -346,7 +346,7 @@ QByteArray QPdf::generateDashes(const QPen &pen) { QByteArray result; ByteStream s(&result); - s << "["; + s << '['; QVector dasharray = pen.dashPattern(); qreal w = pen.widthF(); @@ -357,7 +357,7 @@ QByteArray QPdf::generateDashes(const QPen &pen) if (dw < 0.0001) dw = 0.0001; s << dw; } - s << "]"; + s << ']'; //qDebug() << "dasharray: pen has" << dasharray; //qDebug() << " => " << result; return result; @@ -915,17 +915,17 @@ const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize) QByteArray QPdf::stripSpecialCharacters(const QByteArray &string) { QByteArray s = string; - s.replace(" ", ""); - s.replace("(", ""); - s.replace(")", ""); - s.replace("<", ""); - s.replace(">", ""); - s.replace("[", ""); - s.replace("]", ""); - s.replace("{", ""); - s.replace("}", ""); - s.replace("/", ""); - s.replace("%", ""); + s.replace(' ', ""); + s.replace('(', ""); + s.replace(')', ""); + s.replace('<', ""); + s.replace('>', ""); + s.replace('[', ""); + s.replace(']', ""); + s.replace('{', ""); + s.replace('}', ""); + s.replace('/', ""); + s.replace('%', ""); return s; } diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp index 1d68520..ab60861 100644 --- a/src/gui/painting/qpen.cpp +++ b/src/gui/painting/qpen.cpp @@ -978,7 +978,7 @@ QDebug operator<<(QDebug dbg, const QPen &p) dbg.nospace() << "QPen(" << p.width() << ',' << p.brush() << ',' << int(p.style()) << ',' << int(p.capStyle()) << ',' << int(p.joinStyle()) << ',' << p.dashPattern() - << "," << p.dashOffset() + << ',' << p.dashOffset() << ',' << p.miterLimit() << ')'; return dbg.space(); #else diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp index 2e063b7..e504558 100644 --- a/src/gui/painting/qprintengine_pdf.cpp +++ b/src/gui/painting/qprintengine_pdf.cpp @@ -423,7 +423,7 @@ int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha) object = addXrefEntry(-1); QByteArray alphaDef; QPdf::ByteStream s(&alphaDef); - s << "<<\n/ca " << (brushAlpha/qreal(255.)) << "\n"; + s << "<<\n/ca " << (brushAlpha/qreal(255.)) << '\n'; s << "/CA " << (penAlpha/qreal(255.)) << "\n>>"; xprintf("%s\nendobj\n", alphaDef.constData()); alphaCache.insert(QPair(brushAlpha, penAlpha), object); @@ -1010,7 +1010,7 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font) s << (char)('A' + (tag % 26)); tag /= 26; } - s << "+" << properties.postscriptName << "\n" + s << '+' << properties.postscriptName << "\n" "/Flags " << 4 << "\n" "/FontBBox [" << properties.boundingBox.x()*scale diff --git a/src/gui/painting/qprintengine_ps.cpp b/src/gui/painting/qprintengine_ps.cpp index 97ec640..29f364e 100644 --- a/src/gui/painting/qprintengine_ps.cpp +++ b/src/gui/painting/qprintengine_ps.cpp @@ -167,7 +167,7 @@ static QByteArray wrapDSC(const QByteArray &str) } wrapped += "\n%%+" + tmp; } - return wrapped + "\n"; + return wrapped + '\n'; } // ----------------------------- Internal class declarations ----------------------------- @@ -422,7 +422,7 @@ void QPSPrintEnginePrivate::drawImageHelper(qreal x, qreal y, qreal w, qreal h, << size << " string readstring\n"; ps_r7(*currentPage, out, out.size()); *currentPage << " pop def\n"; - *currentPage << width << ' ' << height << "[" << scaleX << " 0 0 " << scaleY << " 0 0]sl " + *currentPage << width << ' ' << height << '[' << scaleX << " 0 0 " << scaleY << " 0 0]sl " << bits << (!mask.isNull() ? "mask " : "false ") << x << ' ' << y << " di\n"; } @@ -529,7 +529,7 @@ void QPSPrintEnginePrivate::emitHeader(bool finished) else s << "\n%%BoundingBox: 0 0 " << w << h; } - s << "\n" << wrapDSC("%%Creator: " + creator.toUtf8()); + s << '\n' << wrapDSC("%%Creator: " + creator.toUtf8()); if (!title.isEmpty()) s << wrapDSC("%%Title: " + title.toUtf8()); #ifndef QT_NO_DATESTRING @@ -549,7 +549,7 @@ void QPSPrintEnginePrivate::emitHeader(bool finished) "% Prolog copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).\n" "% You may copy this prolog in any way that is directly related to this document.\n" "% For other use of this prolog, see your licensing agreement for Qt.\n" - << ps_header << "\n"; + << ps_header << '\n'; s << "/pageinit {\n"; @@ -560,12 +560,12 @@ void QPSPrintEnginePrivate::emitHeader(bool finished) s << mtop*scale << mleft*scale << "translate\n"; } if (orientation == QPrinter::Portrait) { - s << "% " << printer->widthMM() << "*" << printer->heightMM() + s << "% " << printer->widthMM() << '*' << printer->heightMM() << "mm (portrait)\n0 " << height*scale - << "translate " << scale << "-" << scale << "scale } def\n"; + << "translate " << scale << '-' << scale << "scale } def\n"; } else { - s << "% " << printer->heightMM() << "*" << printer->widthMM() - << " mm (landscape)\n 90 rotate " << scale << "-" << scale << "scale } def\n"; + s << "% " << printer->heightMM() << '*' << printer->widthMM() + << " mm (landscape)\n 90 rotate " << scale << '-' << scale << "scale } def\n"; } s << "%%EndProlog\n"; @@ -619,8 +619,8 @@ void QPSPrintEnginePrivate::flushPage(bool last) QPdf::ByteStream e(&trailer); buffer << "%%Page: " << pageCount << pageCount << "\n" - << "%%BeginPageSetup\n" - << "QI\n"; + "%%BeginPageSetup\n" + "QI\n"; if (hugeDocument) { for (QHash::const_iterator it = fonts.constBegin(); it != fonts.constEnd(); ++it) { @@ -776,8 +776,8 @@ bool QPSPrintEngine::end() d->flushPage(true); QByteArray trailer; QPdf::ByteStream s(&trailer); - s << "%%Trailer\n"; - s << "%%Pages: " << d->pageCount - 1 << "\n" << + s << "%%Trailer\n" + "%%Pages: " << d->pageCount - 1 << '\n' << wrapDSC("%%DocumentFonts: " + d->fontsUsed); s << "%%EOF\n"; d->outDevice->write(trailer); diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index c88af7c..c4cd77a 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -450,9 +450,9 @@ QDebug operator<<(QDebug s, const QRegion &r) { QVector rects = r.rects(); s.nospace() << "QRegion(size=" << rects.size() << "), " - << "bounds = " << r.boundingRect() << "\n"; + << "bounds = " << r.boundingRect() << '\n'; for (int i=0; i innerArea) - qDebug() << "selfTest(): innerRect" << innerRect << "<" << r; + qDebug() << "selfTest(): innerRect" << innerRect << '<' << r; } QRect r = rects.first(); diff --git a/src/gui/painting/qtessellator.cpp b/src/gui/painting/qtessellator.cpp index ce5ab74..b743940 100644 --- a/src/gui/painting/qtessellator.cpp +++ b/src/gui/painting/qtessellator.cpp @@ -1081,7 +1081,7 @@ void QTessellatorPrivate::addIntersection(const Edge *e1, const Edge *e2) yi = y; } QDEBUG() << " between edges " << e1->edge << "and" << e2->edge << "at point (" - << Q27Dot5ToDouble(yi) << ")"; + << Q27Dot5ToDouble(yi) << ')'; Intersection i1; i1.y = yi; @@ -1174,7 +1174,7 @@ void QTessellatorPrivate::addIntersections() for (int i = 0; i < scanline.size; ++i) { Edge *e = scanline.edges[i]; QDEBUG() << " " << i << e->edge << "isect=(" << e->intersect_left << e->intersect_right - << ")"; + << ')'; } #endif @@ -1240,8 +1240,8 @@ QRectF QTessellator::tessellate(const QPointF *points, int nPoints) QDEBUG() << " " << i << ": " << "point=" << d->vertices.position(d->vertices.sorted[i]) << "flags=" << d->vertices.sorted[i]->flags - << "pos=(" << Q27Dot5ToDouble(d->vertices.sorted[i]->x) << "/" - << Q27Dot5ToDouble(d->vertices.sorted[i]->y) << ")"; + << "pos=(" << Q27Dot5ToDouble(d->vertices.sorted[i]->x) << '/' + << Q27Dot5ToDouble(d->vertices.sorted[i]->y) << ')'; } #endif @@ -1271,9 +1271,9 @@ QRectF QTessellator::tessellate(const QPointF *points, int nPoints) for (int i = 0; i < d->scanline.size; ++i) { QDEBUG() << " " << d->scanline.edges[i]->edge << "p0= (" << Q27Dot5ToDouble(d->scanline.edges[i]->v0->x) - << "/" << Q27Dot5ToDouble(d->scanline.edges[i]->v0->y) + << '/' << Q27Dot5ToDouble(d->scanline.edges[i]->v0->y) << ") p1= (" << Q27Dot5ToDouble(d->scanline.edges[i]->v1->x) - << "/" << Q27Dot5ToDouble(d->scanline.edges[i]->v1->y) << ")" + << '/' << Q27Dot5ToDouble(d->scanline.edges[i]->v1->y) << ")" << "x=" << Q27Dot5ToDouble(d->scanline.edges[i]->positionAt(d->y)) << "isLeftOfNext=" << ((i < d->scanline.size - 1) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index ec8c1dc..c00012a 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1020,7 +1020,7 @@ QDebug operator<<(QDebug dbg, const QTransform &m) << " 31=" << m.m31() << " 32=" << m.m32() << " 33=" << m.m33() - << ")"; + << ')'; return dbg.space(); } #endif diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index 3fb63f2..5c37794 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -1646,8 +1646,8 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o if (const QStyleOptionHeader *header = qstyleoption_cast(option)) { QPixmap cache; QString pixmapName = QStyleHelper::uniqueName(QLatin1String("headersection"), option, option->rect.size()); - pixmapName += QLatin1String("-") + QString::number(int(header->position)); - pixmapName += QLatin1String("-") + QString::number(int(header->orientation)); + pixmapName += QString::number(- int(header->position)); + pixmapName += QString::number(- int(header->orientation)); QRect r = option->rect; QColor gradientStopColor; QColor gradientStartColor = option->palette.button().color(); @@ -3858,7 +3858,7 @@ void QCleanlooksStyle::polish(QApplication *app) dataDirs = QLatin1String("/usr/local/share/:/usr/share/"); dataDirs.prepend(QDir::homePath() + QLatin1String("/:")); - d->iconDirs = dataDirs.split(QLatin1String(":")); + d->iconDirs = dataDirs.split(QLatin1Char(':')); #endif } diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index a46dbd7..1285598 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -851,7 +851,7 @@ void QCommonStylePrivate::lookupIconTheme() const dataDirs.prepend(QDir::homePath() + QLatin1String("/:")); QStringList kdeDirs = QString::fromLocal8Bit(getenv("KDEDIRS")).split(QLatin1Char(':')); foreach (const QString &dirName, kdeDirs) - dataDirs.append(QLatin1String(":") + dirName + QLatin1String("/share")); + dataDirs.append(QLatin1Char(':') + dirName + QLatin1String("/share")); iconDirs = dataDirs.split(QLatin1Char(':')); QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde")); @@ -893,7 +893,7 @@ QIconTheme QCommonStylePrivate::parseIndexFile(const QString &themeName) const parents = line.split(QLatin1Char(',')); } - if (line.startsWith(QLatin1String("["))) { + if (line.startsWith(QLatin1Char('['))) { line = line.trimmed(); line.chop(1); QString dirName = line.right(line.length() - 1); diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 587f2b5..91ad64e 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -2845,8 +2845,8 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op if (const QStyleOptionHeader *header = qstyleoption_cast(option)) { QPixmap cache; QString pixmapName = uniqueName(QLatin1String("headersection"), option, option->rect.size()); - pixmapName += QLatin1String("-") + QString::number(int(header->position)); - pixmapName += QLatin1String("-") + QString::number(int(header->orientation)); + pixmapName += QString::number(- int(header->position)); + pixmapName += QString::number(- int(header->orientation)); if (!UsePixmapCache || !QPixmapCache::find(pixmapName, cache)) { cache = QPixmap(option->rect.size()); diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp index 514f67b..3fab682 100644 --- a/src/gui/styles/qstyle.cpp +++ b/src/gui/styles/qstyle.cpp @@ -2439,7 +2439,7 @@ QDebug operator<<(QDebug debug, QStyle::State state) qSort(states); debug << states.join(QLatin1String(" | ")); - debug << ")"; + debug << ')'; return debug; } #endif diff --git a/src/gui/styles/qstyleoption.cpp b/src/gui/styles/qstyleoption.cpp index 5b1bc61..e441101 100644 --- a/src/gui/styles/qstyleoption.cpp +++ b/src/gui/styles/qstyleoption.cpp @@ -5362,10 +5362,10 @@ QDebug operator<<(QDebug debug, const QStyleOption &option) { debug << "QStyleOption("; debug << QStyleOption::OptionType(option.type); - debug << "," << (option.direction == Qt::RightToLeft ? "RightToLeft" : "LeftToRight"); - debug << "," << option.state; - debug << "," << option.rect; - debug << ")"; + debug << ',' << (option.direction == Qt::RightToLeft ? "RightToLeft" : "LeftToRight"); + debug << ',' << option.state; + debug << ',' << option.rect; + debug << ')'; return debug; } #endif diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index fdd51c3..1231561 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -1555,7 +1555,7 @@ QVector QStyleSheetStyle::styleRules(const QWidget *w) const if (widCacheIt == styleSheetCache->constEnd()) { parser.init(wid->styleSheet()); if (!parser.parse(&ss)) { - parser.init(QLatin1String("* {") + wid->styleSheet() + QLatin1String("}")); + parser.init(QLatin1String("* {") + wid->styleSheet() + QLatin1Char('}')); if (!parser.parse(&ss)) qWarning("Could not parse stylesheet of widget %p", wid); } diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 38621c1..0494b72 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -1508,7 +1508,7 @@ QRect Declaration::rectValue() const QStringList func = v.variant.toStringList(); if (func.count() != 2 || func.at(0).compare(QLatin1String("rect")) != 0) return QRect(); - QStringList args = func[1].split(QLatin1String(" "), QString::SkipEmptyParts); + QStringList args = func[1].split(QLatin1Char(' '), QString::SkipEmptyParts); if (args.count() != 4) return QRect(); QRect rect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt()); @@ -2153,7 +2153,7 @@ void Parser::init(const QString &css, bool isFile) if (isFile) { QFile file(css); if (file.open(QFile::ReadOnly)) { - sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1String("/"); + sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1Char('/'); QTextStream stream(&file); styleSheet = stream.readAll(); } else { diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index c3fc9f5..d3020b0 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -792,7 +792,7 @@ static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDe if (! desc.foundry->name.isEmpty() && desc.family->count > 1) { fontDef->family += QString::fromLatin1(" ["); fontDef->family += desc.foundry->name; - fontDef->family += QString::fromLatin1("]"); + fontDef->family += QLatin1Char(']'); } if (desc.style->smoothScalable) @@ -1495,7 +1495,7 @@ QStringList QFontDatabase::families(WritingSystem writingSystem) const if (!foundry.isEmpty()) { str += QLatin1String(" ["); str += foundry; - str += QLatin1String("]"); + str += QLatin1Char(']'); } flist.append(str); } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index d7a9c23..97cb1ed 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -915,7 +915,7 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor) end: qSort(kerning_pairs); // for (int i = 0; i < kerning_pairs.count(); ++i) -// qDebug() << "i" << i << "left_right" << hex << kerning_pairs.at(i).left_right; +// qDebug() << 'i' << i << "left_right" << hex << kerning_pairs.at(i).left_right; } #else diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp index 0d1a884..e4d813d 100644 --- a/src/gui/text/qfontsubset.cpp +++ b/src/gui/text/qfontsubset.cpp @@ -333,17 +333,17 @@ QByteArray QFontSubset::glyphName(unsigned int glyph, const QVector reverse name[0] = 0; } if (name[0]) { - s << "/" << name; + s << '/' << name; } else #endif #if defined(Q_WS_X11) if (fontEngine->type() == QFontEngine::XLFD) { uint uc = static_cast(fontEngine)->toUnicode(glyphIndex); - s << "/" << glyphName(uc, false /* ### */); + s << '/' << glyphName(uc, false /* ### */); } else #endif if (reverseMap[glyphIndex] && reverseMap[glyphIndex] < 0x10000) { - s << "/" << glyphName(reverseMap[glyphIndex], false); + s << '/' << glyphName(reverseMap[glyphIndex], false); } else { s << "/gl" << (int)glyphIndex; } @@ -395,13 +395,13 @@ QByteArray QFontSubset::widthArray() const int endnonlinear = startLinear ? startLinear : g; // qDebug(" startLinear=%x endnonlinear=%x", startLinear,endnonlinear); if (endnonlinear > start) { - s << start << "["; + s << start << '['; for (int i = start; i < endnonlinear; ++i) s << (widths[i]*scale).toInt(); s << "]\n"; } if (startLinear) - s << startLinear << g - 1 << (widths[startLinear]*scale).toInt() << "\n"; + s << startLinear << g - 1 << (widths[startLinear]*scale).toInt() << '\n'; } s << "]\n"; } @@ -488,14 +488,14 @@ QByteArray QFontSubset::createToUnicodeMap() const int endnonlinear = startLinear ? startLinear : g; // qDebug(" startLinear=%x endnonlinear=%x", startLinear,endnonlinear); if (endnonlinear > start) { - s << "<" << QPdf::toHex((ushort)start, buf) << "> <"; + s << '<' << QPdf::toHex((ushort)start, buf) << "> <"; s << QPdf::toHex((ushort)(endnonlinear - 1), buf) << "> "; if (endnonlinear == start + 1) { - s << "<" << QPdf::toHex((ushort)reverseMap[start], buf) << ">\n"; + s << '<' << QPdf::toHex((ushort)reverseMap[start], buf) << ">\n"; } else { - s << "["; + s << '['; for (int i = start; i < endnonlinear; ++i) { - s << "<" << QPdf::toHex((ushort)reverseMap[i], buf) << "> "; + s << '<' << QPdf::toHex((ushort)reverseMap[i], buf) << "> "; } s << "]\n"; } @@ -508,9 +508,9 @@ QByteArray QFontSubset::createToUnicodeMap() const int uc_end = uc_start + len - 1; if ((uc_end >> 8) != (uc_start >> 8)) len = 256 - (uc_start & 0xff); - s << "<" << QPdf::toHex((ushort)startLinear, buf) << "> <"; + s << '<' << QPdf::toHex((ushort)startLinear, buf) << "> <"; s << QPdf::toHex((ushort)(startLinear + len - 1), buf) << "> "; - s << "<" << QPdf::toHex((ushort)reverseMap[startLinear], buf) << ">\n"; + s << '<' << QPdf::toHex((ushort)reverseMap[startLinear], buf) << ">\n"; checkRanges(ts, ranges, nranges); startLinear += len; } @@ -1655,7 +1655,7 @@ QByteArray QFontSubset::toType1() const QByteArray id = QByteArray::number(object_id); QByteArray psname = properties.postscriptName; - psname.replace(" ", ""); + psname.replace(' ', ""); standard_font = false; @@ -1681,12 +1681,12 @@ QByteArray QFontSubset::toType1() const #endif s << "/F" << id << "-Base\n"; if (standard_font) { - s << "/" << psname << " findfont\n" + s << '/' << psname << " findfont\n" "0 dict copy dup /NumGlyphs 0 put dup /CMap 256 array put def\n"; } else { s << "<<\n"; if(!psname.isEmpty()) - s << "/FontName /" << psname << "\n"; + s << "/FontName /" << psname << '\n'; s << "/FontInfo <fsType << ">>\n" "/FontType 1\n" "/PaintType 0\n" @@ -1722,7 +1722,7 @@ QByteArray QFontSubset::type1AddedGlyphs() const int nGlyphs = glyph_indices.size(); QByteArray id = QByteArray::number(object_id); - s << "F" << id << "-Base [\n"; + s << 'F' << id << "-Base [\n"; for (int i = downloaded_glyphs; i < nGlyphs; ++i) { glyph_t g = glyph_indices.at(i); QPainterPath path; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index f3d025c..0958b52 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -82,7 +82,7 @@ #include "private/qapplication_p.h" #include "private/qshortcutmap_p.h" #include -#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1String("\t") + QString(QKeySequence(k)) : QString()) +#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString()) #else #define ACCEL_KEY(k) QString() #endif diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 873f846..23c3c20 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2201,7 +2201,7 @@ void QTextHtmlExporter::emitTextLength(const char *attribute, const QTextLength if (length.type() == QTextLength::PercentageLength) html += QLatin1String("%\""); else - html += QLatin1String("\""); + html += QLatin1Char('\"'); } void QTextHtmlExporter::emitAlignment(Qt::Alignment align) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index ed6205a..a28c655 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -363,7 +363,7 @@ static bool bidiItemize(QTextEngine *engine, QScriptAnalysis *analysis, QBidiCon #if (BIDI_DEBUG >= 2) // qDebug() << "pos=" << current << " dir=" << directions[dir] // << " current=" << directions[dirCurrent] << " last=" << directions[status.last] -// << " eor=" << eor << "/" << directions[status.eor] +// << " eor=" << eor << '/' << directions[status.eor] // << " sor=" << sor << " lastStrong=" // << directions[status.lastStrong] // << " level=" << (int)control.level << " override=" << (bool)control.override; diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index faa4e7b..bed10dc 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -1664,7 +1664,7 @@ QStringList QCompleter::splitPath(const QString& path) const doubleSlash.clear(); #endif - QRegExp re(QLatin1String("[") + QRegExp::escape(sep) + QLatin1String("]")); + QRegExp re(QLatin1Char('[') + QRegExp::escape(sep) + QLatin1Char(']')); QStringList parts = pathCopy.split(re); #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp index a6dcea6..c46c929 100644 --- a/src/gui/util/qsystemtrayicon_win.cpp +++ b/src/gui/util/qsystemtrayicon_win.cpp @@ -662,7 +662,7 @@ void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString //message is limited to 255 chars + NULL QString messageString; if (message.isEmpty() && !title.isEmpty()) - messageString = QLatin1String(" "); //ensures that the message shows when only title is set + messageString = QLatin1Char(' '); //ensures that the message shows when only title is set else messageString = message.left(255) + QChar(); diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index d640c70..09accc7 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1781,8 +1781,8 @@ void QAbstractSpinBoxPrivate::interpret(EmitPolicy ep) q->fixup(tmp); QASBDEBUG() << "QAbstractSpinBoxPrivate::interpret() text '" << edit->displayText() - << "' >> '" << copy << "'" - << "' >> '" << tmp << "'"; + << "' >> '" << copy << '\'' + << "' >> '" << tmp << '\''; doInterpret = tmp != copy && (q->validate(tmp, pos) == QValidator::Acceptable); if (!doInterpret) { diff --git a/src/gui/widgets/qcalendarwidget.cpp b/src/gui/widgets/qcalendarwidget.cpp index 4436c04..8703139 100644 --- a/src/gui/widgets/qcalendarwidget.cpp +++ b/src/gui/widgets/qcalendarwidget.cpp @@ -198,7 +198,7 @@ QString QCalendarDayValidator::text() const { QString str; if (m_day / 10 == 0) - str += QLatin1String("0"); + str += QLatin1Char('0'); str += QString::number(m_day); return highlightString(str, m_pos); } @@ -210,7 +210,7 @@ QString QCalendarDayValidator::text(const QDate &date, int repeat) const } else if (repeat == 2) { QString str; if (date.day() / 10 == 0) - str += QLatin1String("0"); + str += QLatin1Char('0'); return str + QString::number(date.day()); } else if (repeat == 3) { return m_locale.dayName(date.dayOfWeek(), QLocale::ShortFormat); @@ -316,7 +316,7 @@ QString QCalendarMonthValidator::text() const { QString str; if (m_month / 10 == 0) - str += QLatin1String("0"); + str += QLatin1Char('0'); str += QString::number(m_month); return highlightString(str, m_pos); } @@ -328,7 +328,7 @@ QString QCalendarMonthValidator::text(const QDate &date, int repeat) const } else if (repeat == 2) { QString str; if (date.month() / 10 == 0) - str += QLatin1String("0"); + str += QLatin1Char('0'); return str + QString::number(date.month()); } else if (repeat == 3) { return m_locale.standaloneMonthName(date.month(), QLocale::ShortFormat); @@ -432,7 +432,7 @@ QString QCalendarYearValidator::text() const int pow = 10; for (int i = 0; i < 3; i++) { if (m_year / pow == 0) - str += QLatin1String("0"); + str += QLatin1Char('0'); pow *= 10; } str += QString::number(m_year); @@ -445,7 +445,7 @@ QString QCalendarYearValidator::text(const QDate &date, int repeat) const QString str; int year = date.year() % 100; if (year / 10 == 0) - str = QLatin1String("0"); + str = QLatin1Char('0'); return str + QString::number(year); } return QString::number(date.year()); @@ -577,7 +577,7 @@ void QCalendarDateValidator::setFormat(const QString &format) clear(); int pos = 0; - const QLatin1String quote("'"); + const QLatin1Char quote('\''); bool quoting = false; QString separator; while (pos < format.size()) { diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index 016b7c1..1aef133 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -1170,7 +1170,7 @@ void QLabelPrivate::updateShortcut() shortcutCursor.deleteChar(); // remove the ampersand shortcutCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); } else { - if (!text.contains(QLatin1String("&"))) + if (!text.contains(QLatin1Char('&'))) return; hasShortcut = true; shortcutId = q->grabShortcut(QKeySequence::mnemonic(text)); diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 128f243..a4b0b4f 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -79,7 +79,7 @@ #include "private/qapplication_p.h" #include "private/qshortcutmap_p.h" #include "qkeysequence.h" -#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1String("\t") + QString(QKeySequence(k)) : QString()) +#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString()) #else #define ACCEL_KEY(k) QString() #endif diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp index c691eaf..b7426f0 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -1030,7 +1030,7 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, { if (cachedText == input && !input.isEmpty()) { state = cachedState; - QSBDEBUG() << "cachedText was" << "'" << cachedText << "'" << "state was " + QSBDEBUG() << "cachedText was '" << cachedText << "' state was " << state << " and value was " << cachedValue; return cachedValue; @@ -1048,7 +1048,7 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, || (min >= 0 && copy == QLatin1String("+")))) { state = QValidator::Intermediate; QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num; - } else if (copy.startsWith(QLatin1String("-")) && min >= 0) { + } else if (copy.startsWith(QLatin1Char('-')) && min >= 0) { state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100 } else { bool ok = false; @@ -1271,7 +1271,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, { if (cachedText == input && !input.isEmpty()) { state = cachedState; - QSBDEBUG() << "cachedText was" << "'" << cachedText << "'" << "state was " + QSBDEBUG() << "cachedText was '" << cachedText << "' state was " << state << " and value was " << cachedValue; return cachedValue; } -- cgit v0.12 From fa2371e705621b95307f0dbc1988ba048cec6520 Mon Sep 17 00:00:00 2001 From: axasia Date: Sat, 23 May 2009 23:33:49 +0900 Subject: Update japanese translation of Qt Assistant 4.5 --- translations/assistant_ja.ts | 395 ++++++++++++++++++++++--------------------- 1 file changed, 203 insertions(+), 192 deletions(-) diff --git a/translations/assistant_ja.ts b/translations/assistant_ja.ts index 1853155..5e4d2c9 100644 --- a/translations/assistant_ja.ts +++ b/translations/assistant_ja.ts @@ -1,12 +1,12 @@ - + AboutDialog &Close - + é–‰ă˜ă‚‹(&C) @@ -14,18 +14,19 @@ Warning - + è­¦å‘ Unable to launch external application. - + å¤–éƒ¨ă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ă‚’èµ·å‹•ă§ăă¾ă›ă‚“。 + OK - + OK @@ -37,42 +38,42 @@ Bookmarks - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ Add Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă®è¿½å  Bookmark: - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯: Add in Folder: - + 追å å…ˆăƒ•ă‚©ăƒ«ăƒ€: + - + + New Folder - + æ–°ă—ă„ăƒ•ă‚©ăƒ«ăƒ€ Delete Folder - + ăƒ•ă‚©ăƒ«ăƒ€ă‚’å‰é™¤ Rename Folder - + ăƒ•ă‚©ăƒ«ăƒ€ă®åå‰å¤‰æ›´ @@ -80,23 +81,23 @@ Bookmarks - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ Remove - + å‰é™¤ You are going to delete a Folder, this will also<br>remove it's content. Are you sure to continue? - + ăƒ•ă‚©ăƒ«ăƒ€ă‚’å‰é™¤ă™ă‚‹ă¨ä¸­èº«ă‚‚å‰é™¤ă•ă‚Œă¾ă™ăŒă€ç¶ă‘ă¦ă‚ˆă‚ă—ă„ă§ă™ă‹? New Folder - + æ–°ă—ă„ăƒ•ă‚©ăƒ«ăƒ€ @@ -104,47 +105,47 @@ Filter: - + ăƒ•ă‚£ăƒ«ă‚¿: Remove - + å‰é™¤ Delete Folder - + ăƒ•ă‚©ăƒ«ăƒ€ă‚’å‰é™¤ Rename Folder - + ăƒ•ă‚©ăƒ«ăƒ€ă®åå‰å¤‰æ›´ Show Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă‚’é–‹ă Show Bookmark in New Tab - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă Delete Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă‚’å‰é™¤ Rename Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă®åå‰å¤‰æ›´ Add - + è¿½å  @@ -152,48 +153,48 @@ Add new page - + æ–°ă—ă„ăƒăƒ¼ă‚¸ă®è¿½å  Close current page - + ç¾åœ¨ă®ăƒăƒ¼ă‚¸ă‚’é–‰ă˜ă‚‹ Print Document - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă‚’å°åˆ· unknown - + ä¸æ˜ Add New Page - + æ–°ă—ă„ăƒăƒ¼ă‚¸ă®è¿½å  Close This Page - + ă“ă®ăƒăƒ¼ă‚¸ă‚’é–‰ă˜ă‚‹ Close Other Pages - + ä»–ă®ăƒăƒ¼ă‚¸ă‚’é–‰ă˜ă‚‹ Add Bookmark for this Page... - + ă“ă®ăƒăƒ¼ă‚¸ă‚’ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă«è¿½å ... Search - + 検索 @@ -201,12 +202,12 @@ Open Link - + ăƒªăƒ³ă‚¯ă‚’é–‹ă Open Link in New Tab - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă @@ -214,12 +215,12 @@ Add Filter Name - + ăƒ•ă‚£ăƒ«ă‚¿åă‚’è¿½å  Filter Name: - + ăƒ•ă‚£ăƒ«ă‚¿å: @@ -227,27 +228,27 @@ Previous - + æˆ»ă‚‹ Next - + é€²ă‚€ Case Sensitive - + 大文字/å°æ–‡å­—ă‚’åŒºåˆ¥ă™ă‚‹ Whole words - + å˜èªå˜ä½ă§æ¤œç´¢ă™ă‚‹ <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped - + <img src=":/trolltech/assistant/images/wrap.png">&nbsp;見ă¤ă‹ă‚‰ăªă‘ă‚Œă°å…ˆé ­ă‹ă‚‰æ¤œç´¢ă™ă‚‹ @@ -255,27 +256,27 @@ Font - + ăƒ•ă‚©ăƒ³ăƒˆ &Writing system - + æ–‡å­—ă‚»ăƒƒăƒˆ(&W) &Family - + ăƒ•ă‚©ăƒ³ăƒˆå(&F) &Style - + ă‚¹ă‚¿ă‚¤ăƒ«(&S) &Point size - + ă‚µă‚¤ă‚º(&P) @@ -283,38 +284,39 @@ Help - + ăƒ˜ăƒ«ăƒ— OK - + OK <title>Error 404...</title><div align="center"><br><br><h1>The page could not be found</h1><br><h3>'%1'</h3></div> - + <title>Error 404...</title><div align="center"><br><br><h1>ăƒăƒ¼ă‚¸ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“ă§ă—ăŸ</h1><br><h3>'%1'</h3></div> Copy &Link Location - + ăƒªăƒ³ă‚¯ă®URLă‚’ă‚³ăƒ”ăƒ¼(&L) Open Link in New Tab Ctrl+LMB - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă Ctrl+LMB Open Link in New Tab - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă Unable to launch external application. - + å¤–éƒ¨ă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ă‚’èµ·å‹•ă§ăă¾ă›ă‚“。 + @@ -322,17 +324,17 @@ &Look for: - + 検索文字列(&L): Open Link - + ăƒªăƒ³ă‚¯ă‚’é–‹ă Open Link in New Tab - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă @@ -341,97 +343,98 @@ Install Documentation - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ« Downloading documentation info... - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆæƒ…å ±ă‚’ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰ä¸­... Download canceled. - + ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰ă‚’ä¸­æ­¢ă—ă¾ă—ăŸă€‚ Done. - + 完了. The file %1 already exists. Do you want to overwrite it? - + %1 ă¯æ—¢ă«å­˜åœ¨ă—ă¾ă™ă€‚ä¸æ›¸ăă—ă¾ă™ă‹? Unable to save the file %1: %2. - + ăƒ•ă‚¡ă‚¤ăƒ«ă‚’ä¿å­˜ă§ăă¾ă›ă‚“。%1: %2. Downloading %1... - + %1 ă‚’ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰ä¸­... Download failed: %1. - + ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰å¤±æ•—: %1. Documentation info file is corrupt! - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆæƒ…å ±ăƒ•ă‚¡ă‚¤ăƒ«ăŒä¸æ­£ă§ă™! Download failed: Downloaded file is corrupted. - + ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰å¤±æ•—: ăƒ€ă‚¦ăƒ³ăƒ­ăƒ¼ăƒ‰ă—ăŸăƒ•ă‚¡ă‚¤ăƒ«ăŒä¸æ­£ă§ă™ă€‚ Installing documentation %1... - + %1 ă®ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă‚’ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ«ä¸­... Error while installing documentation: %1 - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ«ä¸­ă«ă‚¨ăƒ©ăƒ¼ăŒç™ºç”Ÿă—ă¾ă—ăŸ: +%1 Available Documentation: - + 使用å¯èƒ½ăªăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆ: Install - + ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ« Cancel - + ă‚­ăƒ£ăƒ³ă‚»ăƒ« Close - + é–‰ă˜ă‚‹ Installation Path: - + ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ«å…ˆă®ăƒ‘ă‚¹: ... - + ... @@ -440,298 +443,298 @@ Index - + ă‚¤ăƒ³ăƒ‡ăƒƒă‚¯ă‚¹ Contents - + ă‚³ăƒ³ăƒ†ăƒ³ăƒ„ Bookmarks - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ Search - + 検索 Qt Assistant - + Qt Assistant Unfiltered - + ăƒ•ă‚£ăƒ«ă‚¿ăªă— Page Set&up... - + ăƒăƒ¼ă‚¸è¨­å®(&U)... Print Preview... - + å°åˆ·ăƒ—ăƒ¬ăƒ“ăƒ¥ăƒ¼... &Print... - + å°åˆ·(&P)... New &Tab - + æ–°ă—ă„ă‚¿ăƒ–(&T) &Close Tab - + ă‚¿ăƒ–ă‚’é–‰ă˜ă‚‹(&C) &Quit - + 終了(&Q) CTRL+Q - + CTRL+Q &Copy selected Text - + é¸æ中ă®æ–‡å­—ă‚’ă‚³ăƒ”ăƒ¼(&C) &Find in Text... - + 検索(&F)... Find &Next - + æ¬¡ă‚’æ¤œç´¢(&N) Find &Previous - + å‰ă‚’検索(&P) Preferences... - + 設å®... Zoom &in - + 拡大(&I) Zoom &out - + 縮å°(&O) Normal &Size - + æ™®é€ă®å¤§ăă•(&S) Ctrl+0 - + Ctrl+0 ALT+C - + ALT+C ALT+I - + ALT+I ALT+S - + ALT+S &Home - + ăƒ›ăƒ¼ăƒ (&H) Ctrl+Home - + Ctrl+Home &Back - + æˆ»ă‚‹(&B) &Forward - + é€²ă‚€(&F) Sync with Table of Contents - + 内容ă¨ç›®æ¬¡ă‚’åŒæœŸă™ă‚‹ Next Page - + 次ă®ăƒăƒ¼ă‚¸ Ctrl+Alt+Right - + Ctrl+Alt+Right Previous Page - + å‰ă®ăƒăƒ¼ă‚¸ Ctrl+Alt+Left - + Ctrl+Alt+Left Add Bookmark... - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ă®è¿½å ... About... - + Qt Assistant ă«ă¤ă„ă¦... Navigation Toolbar - + ăƒăƒ“ă‚²ăƒ¼ă‚·ăƒ§ăƒ³ ăƒ„ăƒ¼ăƒ«ăƒăƒ¼ Toolbars - + ăƒ„ăƒ¼ăƒ«ăƒăƒ¼ Filter Toolbar - + ăƒ•ă‚£ăƒ«ă‚¿ăƒ¼ ăƒ„ăƒ¼ăƒ«ăƒăƒ¼ Filtered by: - + ăƒ•ă‚£ăƒ«ă‚¿æ¡ä»¶: Address Toolbar - + ă‚¢ăƒ‰ăƒ¬ă‚¹ ăƒ„ăƒ¼ăƒ«ăƒăƒ¼ Address: - + ă‚¢ăƒ‰ăƒ¬ă‚¹: Could not find the associated content item. - + 関連付ă„ăŸå†…容ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“。 About %1 - + %1 ă«ă¤ă„㦠Updating search index - + æ¤œç´¢ă‚¤ăƒ³ăƒ‡ăƒƒă‚¯ă‚¹ă‚’æ›´æ–°ä¸­ Looking for Qt Documentation... - + Qt ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă‚’æ¢ă—ă¦ă„ă¾ă™... &Window - + ă‚¦ă‚£ăƒ³ăƒ‰ă‚¦(&W) Minimize - + 最å°åŒ– Ctrl+M - + Ctrl+M Zoom - + ă‚ºăƒ¼ăƒ  &File - + ăƒ•ă‚¡ă‚¤ăƒ«(&F) &Edit - + 編集(&E) &View - + 表示(&V) &Go - + ă‚¸ăƒ£ăƒ³ăƒ—(&G) &Bookmarks - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯(&B) &Help - + ăƒ˜ăƒ«ăƒ—(&H) ALT+O - + ALT+O CTRL+D - + CTRL+D @@ -741,47 +744,47 @@ Add Documentation - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®è¿½å  Qt Compressed Help Files (*.qch) - + åœ§ç¸®æ¸ˆă¿ Qt ăƒ˜ăƒ«ăƒ—ăƒ•ă‚¡ă‚¤ăƒ« (*.qch) The specified file is not a valid Qt Help File! - + 指å®ă•ă‚ŒăŸăƒ•ă‚¡ă‚¤ăƒ«ă¯æœ‰å¹ăª Qt ăƒ˜ăƒ«ăƒ— ăƒ•ă‚¡ă‚¤ăƒ«ă§ă¯ă‚ă‚ă¾ă›ă‚“! The namespace %1 is already registered! - + ăƒăƒ¼ăƒ ă‚¹ăƒăƒ¼ă‚¹ %1 ă¯æ—¢ă«ç™»éŒ²æ¸ˆă¿ă§ă™! Remove Documentation - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®é™¤å» Some documents currently opened in Assistant reference the documentation you are attempting to remove. Removing the documentation will close those documents. - + 除å»ă—ă‚ˆă†ă¨ă—ă¦ă„ă‚‹ă„ăă¤ă‹ă®ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă¯ Assistant ä¸ă§å‚ç…§ă•ă‚Œă¦ă„ă¾ă™ă€‚除å»ă™ă‚‹ă¨ă€ă“ă‚Œă‚‰ă®ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă¯é–‰ă˜ă‚‰ă‚Œă¾ă™ă€‚ Cancel - + ă‚­ăƒ£ăƒ³ă‚»ăƒ« OK - + OK Use custom settings - + 独自設å®ă‚’使用ă™ă‚‹ @@ -789,92 +792,92 @@ Preferences - + è¨­å® Fonts - + ăƒ•ă‚©ăƒ³ăƒˆ Font settings: - + ăƒ•ă‚©ăƒ³ăƒˆè¨­å®: Browser - + ăƒ–ăƒ©ă‚¦ă‚¶ăƒ¼ Application - + ă‚¢ăƒ—ăƒªă‚±ăƒ¼ă‚·ăƒ§ăƒ³ Filters - + ăƒ•ă‚£ăƒ«ă‚¿ Filter: - + ăƒ•ă‚£ăƒ«ă‚¿: Attributes: - + å±æ€§: 1 - + 1 Add - + è¿½å  Remove - + å‰é™¤ Documentation - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆ Registered Documentation: - + 登録済ă¿ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆ: Add... - + 追å ... Options - + ă‚ªăƒ—ă‚·ăƒ§ăƒ³ Current Page - + ç¾åœ¨ă®ăƒăƒ¼ă‚¸ Restore to default - + ăƒ‡ăƒ•ă‚©ăƒ«ăƒˆè¨­å®ă«æˆ»ă™ Homepage - + ăƒ›ăƒ¼ăƒ ăƒăƒ¼ă‚¸ @@ -882,64 +885,64 @@ The specified collection file does not exist! - + 指å®ă•ă‚ŒăŸă‚³ăƒ¬ă‚¯ă‚·ăƒ§ăƒ³ăƒ•ă‚¡ă‚¤ăƒ«ă¯å­˜åœ¨ă—ă¾ă›ă‚“! Missing collection file! - + ă‚³ăƒ¬ă‚¯ă‚·ăƒ§ăƒ³ăƒ•ă‚¡ă‚¤ăƒ«ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“! Invalid URL! - + ä¸æ­£ăªURLă§ă™! Missing URL! - + URLăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“! Unknown widget: %1 - + ä¸æ˜ăªă‚¦ă‚£ă‚¸ă‚§ăƒƒăƒˆ: %1 Missing widget! - + ă‚¦ă‚£ă‚¸ă‚§ăƒƒăƒˆăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“! The specified Qt help file does not exist! - + 指å®ă•ă‚ŒăŸ Qt ăƒ˜ăƒ«ăƒ— ăƒ•ă‚¡ă‚¤ăƒ«ăŒå­˜åœ¨ă—ă¾ă›ă‚“! Missing help file! - + ăƒ˜ăƒ«ăƒ—ăƒ•ă‚¡ă‚¤ăƒ«ăŒè¦‹ă¤ă‹ă‚ă¾ă›ă‚“! Missing filter argument! - + ăƒ•ă‚£ăƒ«ă‚¿å¼•æ•°ăŒä¸è¶³ă—ă¦ă„ă¾ă™! Unknown option: %1 - + ä¸æ˜ăªă‚ªăƒ—ă‚·ăƒ§ăƒ³: %1 Qt Assistant - + Qt Assistant @@ -948,12 +951,16 @@ Reason: %2 - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆăƒ•ă‚¡ă‚¤ăƒ«ă‚’ç™»éŒ²ă§ăă¾ă›ă‚“ă§ă—ăŸă€‚ +%1 + +åŸå› : +%2 Documentation successfully registered. - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®ç™»éŒ²ă«æˆåŸă—ă¾ă—ăŸă€‚ @@ -962,28 +969,32 @@ Reason: Reason: %2 - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆăƒ•ă‚¡ă‚¤ăƒ«ă‚’è§£é™¤ă§ăă¾ă›ă‚“ă§ă—ăŸă€‚ +%1 + +åŸå› : +%2 Documentation successfully unregistered. - + ăƒ‰ă‚­ăƒ¥ăƒ¡ăƒ³ăƒˆă®è§£æ”¾ă«æˆåŸă—ă¾ă—ăŸă€‚ Cannot load sqlite database driver! - + SQLite ăƒ‡ăƒ¼ă‚¿ăƒ™ăƒ¼ă‚¹ ăƒ‰ăƒ©ă‚¤ăƒăƒ¼ă‚’ăƒ­ăƒ¼ăƒ‰ă§ăă¾ă›ă‚“! The specified collection file could not be read! - + 指å®ă•ă‚ŒăŸă‚³ăƒ¬ă‚¯ă‚·ăƒ§ăƒ³ăƒ•ă‚¡ă‚¤ăƒ«ă¯èª­ă¿è¾¼ă‚ă¾ă›ă‚“! Bookmark - + ăƒ–ăƒƒă‚¯ăƒăƒ¼ă‚¯ @@ -991,12 +1002,12 @@ Reason: Debugging Remote Control - + ăƒªăƒ¢ăƒ¼ăƒˆ ă‚³ăƒ³ăƒˆăƒ­ăƒ¼ăƒ«ă‚’ăƒ‡ăƒăƒƒă‚°ä¸­ Received Command: %1 %2 - + å—ä¿¡ă—ăŸă‚³ăƒăƒ³ăƒ‰: %1 %2 @@ -1004,28 +1015,28 @@ Reason: &Copy - + ă‚³ăƒ”ăƒ¼(&C) Copy &Link Location - + ăƒªăƒ³ă‚¯ă®URLă‚’ă‚³ăƒ”ăƒ¼(&L) Open Link in New Tab - + ăƒªăƒ³ă‚¯ă‚’æ–°ă—ă„ă‚¿ăƒ–ă§é–‹ă Select All - + ă™ă¹ă¦ă‚’é¸æ Open Link - + ăƒªăƒ³ă‚¯ă‚’é–‹ă @@ -1033,27 +1044,27 @@ Reason: Choose a topic for <b>%1</b>: - + <b>%1</b> ă®æ¤œç´¢å…ˆăƒˆăƒ”ăƒƒă‚¯ă‚’é¸æă—ă¦ăă ă•ă„: Choose Topic - + ăƒˆăƒ”ăƒƒă‚¯ă‚’é¸æ &Topics - + ăƒˆăƒ”ăƒƒă‚¯(&T) &Display - + 表示(&D) &Close - + é–‰ă˜ă‚‹(&C) -- cgit v0.12 From 9edac0287250ff6da9b6998412dba6a432899518 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 25 May 2009 11:36:11 +0200 Subject: Warnings fixed on MSVC simply added Q_UNUSED for parameters that weren't used in a function --- src/corelib/io/qnoncontiguousbytedevice.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp index 6233fde..f50acdb 100644 --- a/src/corelib/io/qnoncontiguousbytedevice.cpp +++ b/src/corelib/io/qnoncontiguousbytedevice.cpp @@ -458,7 +458,9 @@ qint64 QByteDeviceWrappingIoDevice::readData( char * data, qint64 maxSize) qint64 QByteDeviceWrappingIoDevice::writeData( const char* data, qint64 maxSize) { - return -1; + Q_UNUSED(data); + Q_UNUSED(maxSize); + return -1; } /*! -- cgit v0.12 From e5615b9cf4c981bb8d0fec48eacd6c11c124a3b0 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 25 May 2009 11:57:30 +0200 Subject: qdoc: Added some missing qdoc comments. Task-number: 252491 --- src/corelib/io/qfsfileengine.cpp | 2 +- src/gui/painting/qcolor.cpp | 8 +++++++ src/gui/painting/qcolormap_mac.cpp | 6 ----- src/gui/painting/qcolormap_x11.cpp | 4 ---- src/opengl/qgl.cpp | 48 +++++++++++++++++++++++++++++++++----- src/opengl/qgl_win.cpp | 16 +++---------- src/opengl/qgl_wince.cpp | 3 --- src/opengl/qgl_x11.cpp | 30 +++++------------------- 8 files changed, 60 insertions(+), 57 deletions(-) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index e79d867..07f3c9c 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -948,7 +948,7 @@ bool QFSFileEngine::supportsExtension(Extension extension) const For Windows, -2 is always returned. */ -/*! \fn QString QFSFileEngine::owner() const +/*! \fn QString QFSFileEngine::owner(FileOwner own) const \reimp */ diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 1723a19..c50004e 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -2241,4 +2241,12 @@ QDataStream &operator>>(QDataStream &stream, QColor &color) \sa QColor::rgb(), QColor::rgba() */ +/*! \fn void QColormap::initialize() + \internal +*/ + +/*! \fn void QColormap::cleanup() + \internal +*/ + QT_END_NAMESPACE diff --git a/src/gui/painting/qcolormap_mac.cpp b/src/gui/painting/qcolormap_mac.cpp index afe0378..96da90f 100644 --- a/src/gui/painting/qcolormap_mac.cpp +++ b/src/gui/painting/qcolormap_mac.cpp @@ -55,17 +55,11 @@ public: }; static QColormap *qt_mac_global_map = 0; -/*! - Creates the class's internal colormap. - */ void QColormap::initialize() { qt_mac_global_map = new QColormap; } -/*! - Deletes the class's internal colormap. - */ void QColormap::cleanup() { delete qt_mac_global_map; diff --git a/src/gui/painting/qcolormap_x11.cpp b/src/gui/painting/qcolormap_x11.cpp index ccf6955..c9186b1 100644 --- a/src/gui/painting/qcolormap_x11.cpp +++ b/src/gui/painting/qcolormap_x11.cpp @@ -337,8 +337,6 @@ static void init_direct(QColormapPrivate *d, bool ownColormap) static QColormap **cmaps = 0; -/*! \internal -*/ void QColormap::initialize() { Display *display = QX11Info::display(); @@ -578,8 +576,6 @@ void QColormap::initialize() } } -/*! \internal -*/ void QColormap::cleanup() { Display *display = QX11Info::display(); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 8f963f8..ca5c732 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2504,6 +2504,42 @@ const QGLContext* QGLContext::currentContext() visual. On other platforms it may work differently. */ +/*! \fn int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc) + + \bold{Win32 only:} This virtual function chooses a pixel format + that matches the OpenGL \link setFormat() format\endlink. + Reimplement this function in a subclass if you need a custom + context. + + \warning The \a dummyPfd pointer and \a pdc are used as a \c + PIXELFORMATDESCRIPTOR*. We use \c void to avoid using + Windows-specific types in our header files. + + \sa chooseContext() +*/ + +/*! \fn void *QGLContext::chooseVisual() + + \bold{X11 only:} This virtual function tries to find a visual that + matches the format, reducing the demands if the original request + cannot be met. + + The algorithm for reducing the demands of the format is quite + simple-minded, so override this method in your subclass if your + application has spcific requirements on visual selection. + + \sa chooseContext() +*/ + +/*! \fn void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) + \internal + + \bold{X11 only:} This virtual function chooses a visual that matches + the OpenGL \link format() format\endlink. Reimplement this function + in a subclass if you need a custom visual. + + \sa chooseContext() +*/ /*! \fn void QGLContext::reset() @@ -3020,11 +3056,10 @@ void QGLWidget::setFormat(const QGLFormat &format) */ /* - \obsolete - \fn void QGLWidget::setContext(QGLContext *context, - const QGLContext* shareContext, - bool deleteOldContext) + const QGLContext* shareContext, + bool deleteOldContext) + \obsolete Sets a new context for this widget. The QGLContext \a context must be created using \e new. QGLWidget will delete \a context when @@ -3174,9 +3209,10 @@ void QGLWidget::resizeOverlayGL(int, int) { } - +/*! \fn bool QGLWidget::event(QEvent *e) + \reimp +*/ #if !defined(Q_OS_WINCE) && !defined(Q_WS_QWS) -/*! \reimp */ bool QGLWidget::event(QEvent *e) { Q_D(QGLWidget); diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp index bd8569a..217b0fc 100644 --- a/src/opengl/qgl_win.cpp +++ b/src/opengl/qgl_win.cpp @@ -884,19 +884,9 @@ static bool qLogEq(bool a, bool b) return (((!a) && (!b)) || (a && b)); } -/*! - \bold{Win32 only:} This virtual function chooses a pixel - format that matches the OpenGL \link setFormat() format\endlink. - Reimplement this function in a subclass if you need a custom - context. - - \warning The \a dummyPfd pointer and \a pdc are used as a \c - PIXELFORMATDESCRIPTOR*. We use \c void to avoid using - Windows-specific types in our header files. - - \sa chooseContext() -*/ - +/* + See qgl.cpp for qdoc comment. + */ int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc) { Q_D(QGLContext); diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp index cb51598..7429071 100644 --- a/src/opengl/qgl_wince.cpp +++ b/src/opengl/qgl_wince.cpp @@ -552,9 +552,6 @@ void QGLWidgetPrivate::updateColormap() ReleaseDC(q->winId(), hdc); } -/*! - \reimp -\*/ bool QGLWidget::event(QEvent *e) { Q_D(QGLWidget); diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 28c34de..7ed7a23 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -443,19 +443,9 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) return true; } - -/*! - \bold{X11 only:} This virtual function tries to find a - visual that matches the format, reducing the demands if the original - request cannot be met. - - The algorithm for reducing the demands of the format is quite - simple-minded, so override this method in your subclass if your - application has spcific requirements on visual selection. - - \sa chooseContext() -*/ - +/* + See qgl.cpp for qdoc comment. + */ void *QGLContext::chooseVisual() { Q_D(QGLContext); @@ -519,17 +509,9 @@ void *QGLContext::chooseVisual() return vis; } - -/*! - \internal - - \bold{X11 only:} This virtual function chooses a visual - that matches the OpenGL \link format() format\endlink. Reimplement this - function in a subclass if you need a custom visual. - - \sa chooseContext() -*/ - +/* + See qgl.cpp for qdoc comment. + */ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) { Q_D(QGLContext); -- cgit v0.12 From c75d55cfbca0a34ae3ecc171178a8c1f0ae76039 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 25 May 2009 12:02:36 +0200 Subject: Added QT_NO_ANIMATION to qfeatures Now you can opt it out to save disk space (for embedded). Also tested it and fixed code in state machine. --- src/corelib/global/qfeatures.txt | 8 ++++++++ src/corelib/statemachine/qstatemachine.cpp | 13 +++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index 5d63e46..23ec7b0 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -1157,6 +1157,14 @@ Requires: PROPERTIES Name: Accessibility SeeAlso: ??? +Feature: ANIMATION +Description: Provides a framework for animations. +Section: Utilities +Requires: PROPERTIES +Name: Animation +SeeAlso: ??? + + # SVG Feature: SVG diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 309c8be..757584a 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -678,9 +678,11 @@ void QStateMachinePrivate::applyProperties(const QList &tr const QList &exitedStates, const QList &enteredStates) { - Q_Q(QStateMachine); #ifdef QT_NO_ANIMATION Q_UNUSED(transitionList); + Q_UNUSED(exitedStates); +#else + Q_Q(QStateMachine); #endif // Process the property assignments of the entered states. QHash > propertyAssignmentsForState; @@ -851,7 +853,11 @@ void QStateMachinePrivate::applyProperties(const QList &tr // Emit polished signal for entered states that have no animated properties. for (int i = 0; i < enteredStates.size(); ++i) { QState *s = qobject_cast(enteredStates.at(i)); - if (s && !animationsForState.contains(s)) + if (s +#ifndef QT_NO_ANIMATION + && !animationsForState.contains(s) +#endif + ) QStatePrivate::get(s)->emitPolished(); } } @@ -1442,8 +1448,7 @@ void QStateMachinePrivate::unregisterEventTransition(QEventTransition *transitio void QStateMachinePrivate::handleTransitionSignal(const QObject *sender, int signalIndex, void **argv) { - const QVector &connectedSignalIndexes = connections[sender]; - Q_ASSERT(connectedSignalIndexes.at(signalIndex) != 0); + Q_ASSERT(connections[sender].at(signalIndex) != 0); const QMetaObject *meta = sender->metaObject(); QMetaMethod method = meta->method(signalIndex); QList parameterTypes = method.parameterTypes(); -- cgit v0.12 From 44d992ca150d9448cb7b9114b2bc489b441c7b76 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 25 May 2009 12:25:28 +0200 Subject: qdoc: Added some missing qdoc comments. Task-number: 252489 --- src/gui/text/qfont.cpp | 14 ++++++++++++++ src/gui/text/qfont_x11.cpp | 11 ----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index f73ffb5..c5096bf 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1897,6 +1897,20 @@ void QFont::insertSubstitutions(const QString &familyName, } } +/*! \fn void QFont::initialize() + \internal + + Internal function that initializes the font system. The font cache + and font dict do not alloc the keys. The key is a QString which is + shared between QFontPrivate and QXFontName. +*/ + +/*! \fn void QFont::cleanup() + \internal + + Internal function that cleans up the font system. +*/ + // ### mark: should be called removeSubstitutions() /*! Removes all the substitutions for \a familyName. diff --git a/src/gui/text/qfont_x11.cpp b/src/gui/text/qfont_x11.cpp index 710792c..6b0e46c 100644 --- a/src/gui/text/qfont_x11.cpp +++ b/src/gui/text/qfont_x11.cpp @@ -129,13 +129,6 @@ Q_GUI_EXPORT void qt_x11_set_fallback_font_family(int script, const QString &fam int QFontPrivate::defaultEncodingID = -1; -/*! - Internal function that initializes the font system. - - \internal - The font cache and font dict do not alloc the keys. The key is a QString - which is shared between QFontPrivate and QXFontName. -*/ void QFont::initialize() { extern int qt_encoding_id_for_mib(int mib); // from qfontdatabase_x11.cpp @@ -184,10 +177,6 @@ void QFont::initialize() QFontPrivate::defaultEncodingID = qt_encoding_id_for_mib(mib); } -/*! \internal - - Internal function that cleans up the font system. -*/ void QFont::cleanup() { QFontCache::cleanup(); -- cgit v0.12 From 39f1226e937d49b134f545fc63c776cc460a40ca Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 25 May 2009 12:57:48 +0200 Subject: Compile fix --- src/gui/dialogs/qfilesystemmodel.cpp | 2 +- src/gui/itemviews/qdirmodel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index eeca9f9..825f8b6 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -356,7 +356,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS QStringList pathElements = absolutePath.split(QLatin1Char('/'), QString::SkipEmptyParts); if ((pathElements.isEmpty()) #if !defined(Q_OS_WIN) || defined(Q_OS_WINCE) - && QDir::fromNativeSeparators(longPath) != QLatin1Char('/') + && QDir::fromNativeSeparators(longPath) != QLatin1String("/") #endif ) return const_cast(&root); diff --git a/src/gui/itemviews/qdirmodel.cpp b/src/gui/itemviews/qdirmodel.cpp index 5cd16c0..65e3032 100644 --- a/src/gui/itemviews/qdirmodel.cpp +++ b/src/gui/itemviews/qdirmodel.cpp @@ -885,7 +885,7 @@ QModelIndex QDirModel::index(const QString &path, int column) const QStringList pathElements = absolutePath.split(QLatin1Char('/'), QString::SkipEmptyParts); if ((pathElements.isEmpty() || !QFileInfo(path).exists()) #if !defined(Q_OS_WIN) || defined(Q_OS_WINCE) - && path != QLatin1Char('/') + && path != QLatin1String("/") #endif ) return QModelIndex(); -- cgit v0.12 From 7c4735e961fa0e0807d99da1faa2b3fb2a87b6f0 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 25 May 2009 13:23:35 +0200 Subject: Fix a warning on MSVC --- src/gui/painting/qpaintengine_raster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 069f73d..93e0db0 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -536,8 +536,8 @@ bool QRasterPaintEngine::begin(QPaintDevice *device) */ bool QRasterPaintEngine::end() { - Q_D(QRasterPaintEngine); #ifdef QT_DEBUG_DRAW + Q_D(QRasterPaintEngine); qDebug() << "QRasterPaintEngine::end devRect:" << d->deviceRect; if (d->baseClip) { dumpClip(d->rasterBuffer->width(), d->rasterBuffer->height(), d->baseClip); -- cgit v0.12 From 58253fafc6d3c0a535833e674d8930a46138c25f Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 25 May 2009 09:30:20 +0200 Subject: BT: Mac: Crash when using QFontDialog If creating a native QFontDialog and delete it, the native dialog will still show. And worse, it will call the deleted QDialog counterpart. This fix will clean up (and close the native dialog) when the QDialog is deleted. Task-number: 254397 Reviewed-by: Trenton Schulz --- src/gui/dialogs/qfontdialog.cpp | 8 ++++++++ src/gui/dialogs/qfontdialog_mac.mm | 1 + 2 files changed, 9 insertions(+) diff --git a/src/gui/dialogs/qfontdialog.cpp b/src/gui/dialogs/qfontdialog.cpp index 4c5bf4f..aa1c553 100644 --- a/src/gui/dialogs/qfontdialog.cpp +++ b/src/gui/dialogs/qfontdialog.cpp @@ -337,6 +337,14 @@ void QFontDialogPrivate::init() QFontDialog::~QFontDialog() { +#ifdef Q_WS_MAC + Q_D(QFontDialog); + if (d->delegate) { + QFontDialogPrivate::closeCocoaFontPanel(d->delegate); + QFontDialogPrivate::sharedFontPanelAvailable = true; + return; + } +#endif } /*! diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 50917a1..13f7149 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -566,6 +566,7 @@ void *QFontDialogPrivate::openCocoaFontPanel(const QFont &initial, void QFontDialogPrivate::closeCocoaFontPanel(void *delegate) { + QMacCocoaAutoReleasePool pool; QCocoaFontPanelDelegate *theDelegate = static_cast(delegate); NSWindow *ourPanel = [theDelegate actualPanel]; [ourPanel close]; -- cgit v0.12 From 230357435d35a5b379c697723302108dd114585d Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 25 May 2009 14:05:27 +0200 Subject: qdoc: Moved some qdoc comments to a common cpp file. Task-number: 252488 --- src/gui/image/qpixmap.cpp | 95 +++++++++++++++++++++++++++++++++++++++++++ src/gui/image/qpixmap_qws.cpp | 14 ------- src/gui/image/qpixmap_win.cpp | 45 -------------------- src/gui/image/qpixmap_x11.cpp | 28 ------------- 4 files changed, 95 insertions(+), 87 deletions(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 0f6b649..7fcb2b9 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -2014,4 +2014,99 @@ QPixmapData* QPixmap::pixmapData() const return data; } +/*! + \enum QPixmap::HBitmapFormat + + \bold{Win32 only:} This enum defines how the conversion between \c + HBITMAP and QPixmap is performed. + + \warning This enum is only available on Windows. + + \value NoAlpha The alpha channel is ignored and always treated as + being set to fully opaque. This is preferred if the \c HBITMAP is + used with standard GDI calls, such as \c BitBlt(). + + \value PremultipliedAlpha The \c HBITMAP is treated as having an + alpha channel and premultiplied colors. This is preferred if the + \c HBITMAP is accessed through the \c AlphaBlend() GDI function. + + \value Alpha The \c HBITMAP is treated as having a plain alpha + channel. This is the preferred format if the \c HBITMAP is going + to be used as an application icon or systray icon. + + \sa fromWinHBITMAP(), toWinHBITMAP() +*/ + +/*! \fn HBITMAP QPixmap::toWinHBITMAP(HBitmapFormat format) const + \bold{Win32 only:} Creates a \c HBITMAP equivalent to the QPixmap, + based on the given \a format. Returns the \c HBITMAP handle. + + It is the caller's responsibility to free the \c HBITMAP data + after use. + + \warning This function is only available on Windows. + + \sa fromWinHBITMAP() +*/ + +/*! \fn QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format) + \bold{Win32 only:} Returns a QPixmap that is equivalent to the + given \a bitmap. The conversion is based on the specified \a + format. + + \warning This function is only available on Windows. + + \sa toWinHBITMAP(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} + +*/ + +/*! \fn const QX11Info &QPixmap::x11Info() const + \bold{X11 only:} Returns information about the configuration of + the X display used to display the widget. + + \warning This function is only available on X11. + + \sa {QPixmap#Pixmap Information}{Pixmap Information} +*/ + +/*! \fn Qt::HANDLE QPixmap::x11PictureHandle() const + \bold{X11 only:} Returns the X11 Picture handle of the pixmap for + XRender support. + + This function will return 0 if XRender support is not compiled + into Qt, if the XRender extension is not supported on the X11 + display, or if the handle could not be created. Use of this + function is not portable. + + \warning This function is only available on X11. + + \sa {QPixmap#Pixmap Information}{Pixmap Information} +*/ + +/*! \fn int QPixmap::x11SetDefaultScreen(int screen) + \internal +*/ + +/*! \fn void QPixmap::x11SetScreen(int screen) + \internal +*/ + +/*! \fn QRgb* QPixmap::clut() const + \internal +*/ + +/*! \fn int QPixmap::numCols() const + \internal +*/ + +/*! \fn const uchar* QPixmap::qwsBits() const + \internal + \since 4.1 +*/ + +/*! \fn int QPixmap::qwsBytesPerLine() const + \internal + \since 4.1 +*/ + QT_END_NAMESPACE diff --git a/src/gui/image/qpixmap_qws.cpp b/src/gui/image/qpixmap_qws.cpp index 6cc7981..7e383ab 100644 --- a/src/gui/image/qpixmap_qws.cpp +++ b/src/gui/image/qpixmap_qws.cpp @@ -109,9 +109,6 @@ QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h) return QPixmap::fromImage(img); } -/*! - \internal -*/ QRgb* QPixmap::clut() const { if (data->classId() == QPixmapData::RasterClass) { @@ -122,9 +119,6 @@ QRgb* QPixmap::clut() const return 0; } -/*! - \internal -*/ int QPixmap::numCols() const { if (data->classId() == QPixmapData::RasterClass) { @@ -135,10 +129,6 @@ int QPixmap::numCols() const return 0; } -/*! - \internal - \since 4.1 -*/ const uchar* QPixmap::qwsBits() const { if (data->classId() == QPixmapData::RasterClass) { @@ -149,10 +139,6 @@ const uchar* QPixmap::qwsBits() const return 0; } -/*! - \internal - \since 4.1 -*/ int QPixmap::qwsBytesPerLine() const { if (data->classId() == QPixmapData::RasterClass) { diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index cbe9004..6a8b38a 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -119,42 +119,6 @@ QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h ) return pixmap; } - - -/*! - \enum QPixmap::HBitmapFormat - - This enum defines how the conversion between \c HBITMAP - and QPixmap is performed. - - \warning This enum is only available on Windows. - - \value NoAlpha The alpha channel is ignored and always treated as - being set to fully opaque. This is preferred if the \c HBITMAP is - used with standard GDI calls, such as \c BitBlt(). - - \value PremultipliedAlpha The \c HBITMAP is treated as having an - alpha channel and premultiplied colors. This is preferred if the - \c HBITMAP is accessed through the \c AlphaBlend() GDI function. - - \value Alpha The \c HBITMAP is treated as having a plain alpha - channel. This is the preferred format if the \c HBITMAP is going - to be used as an application icon or systray icon. - - \sa fromWinHBITMAP(), toWinHBITMAP() -*/ - -/*! - Creates a \c HBITMAP equivalent to the QPixmap, based on the given - \a format. Returns the \c HBITMAP handle. - - It is the caller's responsibility to free the \c HBITMAP data - after use. - - \warning This function is only available on Windows. - - \sa fromWinHBITMAP() -*/ HBITMAP QPixmap::toWinHBITMAP(HBitmapFormat format) const { HBITMAP bitmap = 0; @@ -209,15 +173,6 @@ HBITMAP QPixmap::toWinHBITMAP(HBitmapFormat format) const return bitmap; } -/*! - Returns a QPixmap that is equivalent to the given \a bitmap. The - conversion is based on the specified \a format. - - \warning This function is only available on Windows. - - \sa toWinHBITMAP(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} - -*/ QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format) { // Verify size diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 38916c7..d2e8d84 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -1914,9 +1914,6 @@ QPixmap QX11PixmapData::transformed(const QTransform &transform, } } -/*! - \internal -*/ int QPixmap::x11SetDefaultScreen(int screen) { int old = defaultScreen; @@ -1924,9 +1921,6 @@ int QPixmap::x11SetDefaultScreen(int screen) return old; } -/*! - \internal -*/ void QPixmap::x11SetScreen(int screen) { if (paintingActive()) { @@ -2034,14 +2028,6 @@ bool QX11PixmapData::hasAlphaChannel() const return d == 32; } -/*! - Returns information about the configuration of the X display used to display - the widget. - - \warning This function is only available on X11. - - \sa {QPixmap#Pixmap Information}{Pixmap Information} -*/ const QX11Info &QPixmap::x11Info() const { if (data->classId() == QPixmapData::X11Class) @@ -2098,20 +2084,6 @@ QPaintEngine* QX11PixmapData::paintEngine() const return that->pengine; } -/*! - Returns the X11 Picture handle of the pixmap for XRender - support. - - This function will return 0 if XRender support is not compiled - into Qt, if the XRender extension is not supported on the X11 - display, or if the handle could not be created. Use of this - function is not portable. - - \warning This function is only available on X11. - - \sa {QPixmap#Pixmap Information}{Pixmap Information} -*/ - Qt::HANDLE QPixmap::x11PictureHandle() const { #ifndef QT_NO_XRENDER -- cgit v0.12 From ee443b7873586592773190457ce8d21bcaae248e Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 25 May 2009 14:21:16 +0200 Subject: qdoc: Fixed non-well-formed XML. Reviewed-by: Martin Smith --- tools/qdoc3/htmlgenerator.cpp | 2 +- tools/qdoc3/test/classic.css | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index e271338..798cbb5 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -2202,7 +2202,7 @@ void HtmlGenerator::generateSectionList(const Section& section, if (name_alignment) { out() << ""; + << "align=\"right\" valign=\"top\">"; } else { if (twoColumn && i == (int) (section.members.count() + 1) / 2) diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css index e700e0a..22f1668 100644 --- a/tools/qdoc3/test/classic.css +++ b/tools/qdoc3/test/classic.css @@ -83,6 +83,7 @@ table td.memItemLeft { border-left-style: none; background-color: #FAFAFA; font-size: 80%; + white-space: nowrap } table td.memItemRight { padding: 1px 8px 0px 8px; -- cgit v0.12 From 1a477dcad1171d2d195422072fce62fc936e56cb Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 25 May 2009 14:46:20 +0200 Subject: Changed qdoc program to display version from QT_VERSION_STR. Task-number: 251486 --- tools/qdoc3/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp index 3e6f832..5c247fa 100644 --- a/tools/qdoc3/main.cpp +++ b/tools/qdoc3/main.cpp @@ -43,6 +43,7 @@ main.cpp */ +#include #include #include #include "apigenerator.h" @@ -136,7 +137,8 @@ static void printHelp() */ static void printVersion() { - Location::information(tr("qdoc version 4.4.1")); + QString s = QString(tr("qdoc version ")) + QString(QT_VERSION_STR); + Location::information(s); } /*! -- cgit v0.12 From b6b251cb8b36be434cf878a916c15019fd65b6f0 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 25 May 2009 14:46:47 +0200 Subject: Removed some export to symbols that don't need it ...hopefully --- examples/animation/sub-attaq/qanimationstate.cpp | 45 +++++++----------------- examples/animation/sub-attaq/qanimationstate.h | 4 +-- src/corelib/concurrent/qfuturewatcher_p.h | 4 +-- src/corelib/kernel/qabstractitemmodel_p.h | 2 +- src/corelib/kernel/qeventdispatcher_unix_p.h | 4 +-- src/corelib/statemachine/qabstractstate_p.h | 3 +- src/corelib/statemachine/qstate.cpp | 14 -------- src/corelib/statemachine/qstate_p.h | 6 ++-- src/corelib/statemachine/qstatemachine_p.h | 5 ++- 9 files changed, 25 insertions(+), 62 deletions(-) diff --git a/examples/animation/sub-attaq/qanimationstate.cpp b/examples/animation/sub-attaq/qanimationstate.cpp index 26e0ef3..d4d109c 100644 --- a/examples/animation/sub-attaq/qanimationstate.cpp +++ b/examples/animation/sub-attaq/qanimationstate.cpp @@ -42,8 +42,6 @@ #include "qanimationstate.h" #include -#include - QT_BEGIN_NAMESPACE @@ -76,25 +74,11 @@ machine.start(); #ifndef QT_NO_ANIMATION -class QAnimationStatePrivate : public QStatePrivate -{ - Q_DECLARE_PUBLIC(QAnimationState) -public: - QAnimationStatePrivate() - : animation(0) - { - - } - ~QAnimationStatePrivate() {} - - QAbstractAnimation *animation; -}; - /*! Constructs a new state with the given \a parent state. */ QAnimationState::QAnimationState(QState *parent) - : QState(*new QAnimationStatePrivate, parent) + : QState(parent), m_animation(0) { } @@ -112,20 +96,18 @@ QAnimationState::~QAnimationState() */ void QAnimationState::setAnimation(QAbstractAnimation *animation) { - Q_D(QAnimationState); - - if (animation == d->animation) + if (animation == m_animation) return; //Disconnect from the previous animation if exist - if(d->animation) - disconnect(d->animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); + if(m_animation) + disconnect(m_animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); - d->animation = animation; + m_animation = animation; - if (d->animation) { + if (m_animation) { //connect the new animation - connect(d->animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); + connect(m_animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); } } @@ -134,8 +116,7 @@ void QAnimationState::setAnimation(QAbstractAnimation *animation) */ QAbstractAnimation* QAnimationState::animation() const { - Q_D(const QAnimationState); - return d->animation; + return m_animation; } /*! @@ -143,9 +124,8 @@ QAbstractAnimation* QAnimationState::animation() const */ void QAnimationState::onEntry(QEvent *) { - Q_D(QAnimationState); - if (d->animation) - d->animation->start(); + if (m_animation) + m_animation->start(); } /*! @@ -153,9 +133,8 @@ void QAnimationState::onEntry(QEvent *) */ void QAnimationState::onExit(QEvent *) { - Q_D(QAnimationState); - if (d->animation) - d->animation->stop(); + if (m_animation) + m_animation->stop(); } /*! diff --git a/examples/animation/sub-attaq/qanimationstate.h b/examples/animation/sub-attaq/qanimationstate.h index 88c0a6d..e5322ad 100644 --- a/examples/animation/sub-attaq/qanimationstate.h +++ b/examples/animation/sub-attaq/qanimationstate.h @@ -58,7 +58,7 @@ QT_MODULE(Gui) #ifndef QT_NO_ANIMATION -class QAnimationStatePrivate; +class QAbstractAnimation; class QAnimationState : public QState { @@ -80,7 +80,7 @@ protected: private: Q_DISABLE_COPY(QAnimationState) - Q_DECLARE_PRIVATE(QAnimationState) + QAbstractAnimation *m_animation; }; #endif diff --git a/src/corelib/concurrent/qfuturewatcher_p.h b/src/corelib/concurrent/qfuturewatcher_p.h index 324839d..d53a1bd 100644 --- a/src/corelib/concurrent/qfuturewatcher_p.h +++ b/src/corelib/concurrent/qfuturewatcher_p.h @@ -63,8 +63,8 @@ QT_BEGIN_NAMESPACE class QFutureWatcherBase; -class Q_CORE_EXPORT QFutureWatcherBasePrivate : public QObjectPrivate, - public QFutureCallOutInterface +class QFutureWatcherBasePrivate : public QObjectPrivate, + public QFutureCallOutInterface { Q_DECLARE_PUBLIC(QFutureWatcherBase) diff --git a/src/corelib/kernel/qabstractitemmodel_p.h b/src/corelib/kernel/qabstractitemmodel_p.h index df1a6ce..27f1b28 100644 --- a/src/corelib/kernel/qabstractitemmodel_p.h +++ b/src/corelib/kernel/qabstractitemmodel_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE -class Q_CORE_EXPORT QPersistentModelIndexData +class QPersistentModelIndexData { public: QPersistentModelIndexData() : model(0) {} diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index 41329cf..8c08bd2 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -153,14 +153,14 @@ public: int activateTimers(); }; -struct Q_CORE_EXPORT QSockNot +struct QSockNot { QSocketNotifier *obj; int fd; fd_set *queue; }; -class Q_CORE_EXPORT QSockNotType +class QSockNotType { public: QSockNotType(); diff --git a/src/corelib/statemachine/qabstractstate_p.h b/src/corelib/statemachine/qabstractstate_p.h index 2aad47e..b4f3108 100644 --- a/src/corelib/statemachine/qabstractstate_p.h +++ b/src/corelib/statemachine/qabstractstate_p.h @@ -60,8 +60,7 @@ QT_BEGIN_NAMESPACE class QStateMachine; class QAbstractState; -class Q_CORE_EXPORT QAbstractStatePrivate - : public QObjectPrivate +class QAbstractStatePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QAbstractState) diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index e42e463..5463059 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -129,20 +129,6 @@ QStatePrivate::~QStatePrivate() { } -QStatePrivate *QStatePrivate::get(QState *q) -{ - if (!q) - return 0; - return q->d_func(); -} - -const QStatePrivate *QStatePrivate::get(const QState *q) -{ - if (!q) - return 0; - return q->d_func(); -} - void QStatePrivate::emitFinished() { Q_Q(QState); diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h index 1f913b4..491cb87 100644 --- a/src/corelib/statemachine/qstate_p.h +++ b/src/corelib/statemachine/qstate_p.h @@ -79,15 +79,15 @@ class QAbstractTransition; class QHistoryState; class QState; -class Q_CORE_EXPORT QStatePrivate : public QAbstractStatePrivate +class QStatePrivate : public QAbstractStatePrivate { Q_DECLARE_PUBLIC(QState) public: QStatePrivate(); ~QStatePrivate(); - static QStatePrivate *get(QState *q); - static const QStatePrivate *get(const QState *q); + static QStatePrivate *get(QState *q) { return q ? q->d_func() : 0; } + static const QStatePrivate *get(const QState *q) { return q? q->d_func() : 0; } QList childStates() const; QList historyStates() const; diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index dfa5575..54953b4 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -81,8 +81,7 @@ class QAbstractAnimation; #endif class QStateMachine; -class Q_CORE_EXPORT QStateMachinePrivate - : public QObjectPrivate +class QStateMachinePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QStateMachine) public: @@ -209,7 +208,7 @@ public: f_cloneEvent cloneEvent; }; - static const Handler *handler; + static Q_CORE_EXPORT const Handler *handler; }; QT_END_NAMESPACE -- cgit v0.12 From e77f2e595d9b9a6f078f37894733c52bbcfeb695 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 25 May 2009 14:55:33 +0200 Subject: BT: Prevent crash in Designer when using a scroll wheel to change a property. There was some strangeness happening here with parents, but the main problem was the fact that wheel was getting sent to the focusframe and not to the widget below. However, the focusframe has the "transparent for mouse events" flag set and wheel events probably should be transparent as well. Task-number: 253539 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qcocoaview_mac.mm | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 4ceae3f..f1a7f39 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -789,10 +789,22 @@ extern "C" { bool wheelOK = false; Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]); + QWidget *widgetToGetMouse = qwidget; + if (widgetToGetMouse->testAttribute(Qt::WA_TransparentForMouseEvents)) { + // Simulate passing the event through since Cocoa doesn't do that for us. + // Start by building a tree up. + NSView *candidateView = [self viewUnderTransparentForMouseView:self + widget:widgetToGetMouse + withWindowPoint:windowPoint]; + if (candidateView != nil) { + widgetToGetMouse = QWidget::find(WId(candidateView)); + } + } + // Mouse wheel deltas seem to tick in at increments of 0.1. Qt widgets - // expect the delta to be a multiple of 120. + // expect the delta to be a multiple of 120. const int ScrollFactor = 10 * 120; - // The qMax(...) factor reduces the + // The qMax(...) factor reduces the // acceleration for large wheel deltas. int deltaX = [theEvent deltaX] * ScrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaX])); int deltaY = [theEvent deltaY] * ScrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaY])); @@ -800,10 +812,10 @@ extern "C" { if (deltaX != 0) { QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal); - qt_sendSpontaneousEvent(qwidget, &qwe); + qt_sendSpontaneousEvent(widgetToGetMouse, &qwe); wheelOK = qwe.isAccepted(); if (!wheelOK && QApplicationPrivate::focus_widget - && QApplicationPrivate::focus_widget != qwidget) { + && QApplicationPrivate::focus_widget != widgetToGetMouse) { QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(qglobal), qglobal, deltaX, buttons, keyMods, Qt::Horizontal); qt_sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2); @@ -813,10 +825,10 @@ extern "C" { if (deltaY) { QWheelEvent qwe(qlocal, qglobal, deltaY, buttons, keyMods, Qt::Vertical); - qt_sendSpontaneousEvent(qwidget, &qwe); + qt_sendSpontaneousEvent(widgetToGetMouse, &qwe); wheelOK = qwe.isAccepted(); if (!wheelOK && QApplicationPrivate::focus_widget - && QApplicationPrivate::focus_widget != qwidget) { + && QApplicationPrivate::focus_widget != widgetToGetMouse) { QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(qglobal), qglobal, deltaY, buttons, keyMods, Qt::Vertical); qt_sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2); @@ -828,10 +840,10 @@ extern "C" { // Qt doesn't explicitly support wheels with a Z component. In a misguided attempt to // try to be ahead of the pack, I'm adding this extra value. QWheelEvent qwe(qlocal, qglobal, deltaZ, buttons, keyMods, (Qt::Orientation)3); - qt_sendSpontaneousEvent(qwidget, &qwe); + qt_sendSpontaneousEvent(widgetToGetMouse, &qwe); wheelOK = qwe.isAccepted(); if (!wheelOK && QApplicationPrivate::focus_widget - && QApplicationPrivate::focus_widget != qwidget) { + && QApplicationPrivate::focus_widget != widgetToGetMouse) { QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(qglobal), qglobal, deltaZ, buttons, keyMods, (Qt::Orientation)3); qt_sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2); -- cgit v0.12 From b57d3f8169c6f1a1aab7203d79043a5f691b7e3e Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 25 May 2009 15:06:49 +0200 Subject: Changed qdoc to simplify the output for overloaded functions. Task-number: 249222 --- tools/qdoc3/doc.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index 61d0ed6..397fbfa 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -1265,9 +1265,7 @@ void DocParser::parse(const QString& source, } else { append(Atom::ParaLeft); - append(Atom::String, - "This is an overloaded member function, " - "provided for convenience."); + append(Atom::String,"This is an overloaded function."); append(Atom::ParaRight); x = getMetaCommandArgument(cmdStr); } -- cgit v0.12 From 46bb023374dfd8684cefbe1d1c4ffc37f64f1239 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Mon, 25 May 2009 16:25:41 +0200 Subject: Adding details to QSettings functions Adding details to the documentation of custom storage format and related functions. Task-number: 207865 Rev-by: David Boddie Rev-by: Marius Storm-Olsen --- src/corelib/io/qsettings.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 14fc2d4..6152518 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -3468,7 +3468,7 @@ void QSettings::setPath(Format format, Scope scope, const QString &path) \typedef QSettings::SettingsMap Typedef for QMap. - + \sa registerFormat() */ @@ -3479,6 +3479,11 @@ void QSettings::setPath(Format format, Scope scope, const QString &path) \snippet doc/src/snippets/code/src_corelib_io_qsettings.cpp 27 + \c ReadFunc is used in \c registerFormat() as a pointer to a function + that reads a set of key/value pairs. \c ReadFunc should read all the + options in one pass, and return all the settings in the \c SettingsMap + container, which is initially empty. + \sa WriteFunc, registerFormat() */ @@ -3489,6 +3494,10 @@ void QSettings::setPath(Format format, Scope scope, const QString &path) \snippet doc/src/snippets/code/src_corelib_io_qsettings.cpp 28 + \c WriteFunc is used in \c registerFormat() as a pointer to a function + that writes a set of key/value pairs. \c WriteFunc is only called once, + so you need to output the settings in one go. + \sa ReadFunc, registerFormat() */ @@ -3504,7 +3513,7 @@ void QSettings::setPath(Format format, Scope scope, const QString &path) extension associated to the format (without the '.'). The \a readFunc and \a writeFunc parameters are pointers to - functions that read and write a set of (key, value) pairs. The + functions that read and write a set of key/value pairs. The QIODevice parameter to the read and write functions is always opened in binary mode (i.e., without the QIODevice::Text flag). -- cgit v0.12 From 9021113c583cc6b54b3b764e8e74d1448474c773 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 25 May 2009 16:32:25 +0200 Subject: startup crash on WinCE need to deploy the sqlite plugin, otherwise no model gets created, but referenced causing a crash. Task-number: 254435 Reviewed-by: joerg BT: yes --- examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro b/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro index 1881fce..c216a30 100644 --- a/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro +++ b/examples/sql/sqlwidgetmapper/sqlwidgetmapper.pro @@ -8,3 +8,6 @@ target.path = $$[QT_INSTALL_EXAMPLES]/sql/sqlwidgetmapper sources.files = $$SOURCES $$HEADERS *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/sql/sqlwidgetmapper INSTALLS += target sources + +wince*: DEPLOYMENT_PLUGIN += qsqlite + -- cgit v0.12 From 3d560a498803fadfec9163d7a9695aee60cca8d4 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 25 May 2009 16:26:13 +0200 Subject: BT: fix systray balloon crash bug on Windows CE Its the context menu handling code... again. Problem is, that during execution of translateMouseEvent, the widget is closed and a modal message box is shown. After that, there's no widget at globalPos and thus, alienWidget is null. This patch just adds a null check for alienWidget. Task-number: 254425 Reviewed-by: mauricek BT: yes --- src/gui/kernel/qapplication_win.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index f14ad6f..239ee14 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -1675,20 +1675,23 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam // send the context menu event is a different one if (!alienWidget->testAttribute(Qt::WA_NativeWindow) && !alienWidget->testAttribute(Qt::WA_PaintOnScreen)) { alienWidget = QApplication::widgetAt(globalPos); - pos = alienWidget->mapFromGlobal(globalPos); + if (alienWidget) + pos = alienWidget->mapFromGlobal(globalPos); } - SHRGINFO shrg; - shrg.cbSize = sizeof(shrg); - shrg.hwndClient = hwnd; - shrg.ptDown.x = GET_X_LPARAM(lParam); - shrg.ptDown.y = GET_Y_LPARAM(lParam); - shrg.dwFlags = SHRG_RETURNCMD | SHRG_NOANIMATION; - resolveAygLibs(); - if (ptrRecognizeGesture && (ptrRecognizeGesture(&shrg) == GN_CONTEXTMENU)) { - if (qApp->activePopupWidget()) - qApp->activePopupWidget()->close(); - QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos); - result = qt_sendSpontaneousEvent(alienWidget, &e); + if (alienWidget) { + SHRGINFO shrg; + shrg.cbSize = sizeof(shrg); + shrg.hwndClient = hwnd; + shrg.ptDown.x = GET_X_LPARAM(lParam); + shrg.ptDown.y = GET_Y_LPARAM(lParam); + shrg.dwFlags = SHRG_RETURNCMD | SHRG_NOANIMATION; + resolveAygLibs(); + if (ptrRecognizeGesture && (ptrRecognizeGesture(&shrg) == GN_CONTEXTMENU)) { + if (qApp->activePopupWidget()) + qApp->activePopupWidget()->close(); + QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos); + result = qt_sendSpontaneousEvent(alienWidget, &e); + } } } } -- cgit v0.12 From 0f0fc963a7f1691038ee36a27bb63ff3165eefba Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 25 May 2009 16:45:57 +0200 Subject: BT:Fix a clipping issue in tabbar tabs On XP and Vista where tabs use taboverlap, the currently dragged would loose the outline. We need to compensate for the taboverlap when creating the draggable widget, otherwise the outline will be clipped. Task-number: 254453 Reviewed-by: nrc --- src/gui/widgets/qtabbar.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 69221ba..785d772 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -1536,9 +1536,10 @@ void QTabBar::paintEvent(QPaintEvent *) } if (!d->dragInProgress) p.drawControl(QStyle::CE_TabBarTab, tab); - else - d->movingTab->setGeometry(tab.rect); - + else { + int taboverlap = style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0, this); + d->movingTab->setGeometry(tab.rect.adjusted(-taboverlap, 0, taboverlap, 0)); + } } // Only draw the tear indicator if necessary. Most of the time we don't need too. @@ -1805,7 +1806,9 @@ void QTabBarPrivate::setupMovableTab() if (!movingTab) movingTab = new QWidget(q); + int taboverlap = q->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 ,q); QRect grabRect = q->tabRect(pressedIndex); + grabRect.adjust(-taboverlap, 0, taboverlap, 0); QPixmap grabImage(grabRect.size()); grabImage.fill(Qt::transparent); @@ -1813,7 +1816,7 @@ void QTabBarPrivate::setupMovableTab() QStyleOptionTabV3 tab; q->initStyleOption(&tab, pressedIndex); - tab.rect.moveTopLeft(QPoint(0, 0)); + tab.rect.moveTopLeft(QPoint(taboverlap, 0)); p.drawControl(QStyle::CE_TabBarTab, tab); p.end(); -- cgit v0.12 From 313e2719ac75eb6c6ff2d84f5cef9f70433d5943 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 25 May 2009 16:57:43 +0200 Subject: add deployment rules... WinCE needs those files to be able to do something useful Task-number: 254430 Task-number: 254437 Task-number: 254428 Reviewed-by: joerg BT: yes --- examples/itemviews/puzzle/puzzle.pro | 5 +++++ examples/qtconcurrent/imagescaling/imagescaling.pro | 2 ++ examples/widgets/movie/movie.pro | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/examples/itemviews/puzzle/puzzle.pro b/examples/itemviews/puzzle/puzzle.pro index deed112..4f5aaad 100644 --- a/examples/itemviews/puzzle/puzzle.pro +++ b/examples/itemviews/puzzle/puzzle.pro @@ -12,3 +12,8 @@ target.path = $$[QT_INSTALL_EXAMPLES]/itemviews/puzzle sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.jpg sources.path = $$[QT_INSTALL_EXAMPLES]/itemviews/puzzle INSTALLS += target sources + +wince* { + DEPLOYMENT_PLUGIN += qjpeg qgif qtiff +} + diff --git a/examples/qtconcurrent/imagescaling/imagescaling.pro b/examples/qtconcurrent/imagescaling/imagescaling.pro index fbf864a..0a25efb 100644 --- a/examples/qtconcurrent/imagescaling/imagescaling.pro +++ b/examples/qtconcurrent/imagescaling/imagescaling.pro @@ -11,3 +11,5 @@ target.path = $$[QT_INSTALL_EXAMPLES]/qtconcurrent/imagescaling sources.files = $$SOURCES $$HEADERS $$FORMS $$RESOURCES *.pro *.png sources.path = $$[QT_INSTALL_EXAMPLES]/qtconcurrent/imagescaling INSTALLS += target sources + +wince*: DEPLOYMENT_PLUGIN += qgif qjpeg qtiff diff --git a/examples/widgets/movie/movie.pro b/examples/widgets/movie/movie.pro index 1c7cbae..6aa5780 100644 --- a/examples/widgets/movie/movie.pro +++ b/examples/widgets/movie/movie.pro @@ -7,3 +7,11 @@ target.path = $$[QT_INSTALL_EXAMPLES]/widgets/movie sources.files = $$SOURCES $$HEADERS $$RESOURCES movie.pro animation.mng sources.path = $$[QT_INSTALL_EXAMPLES]/widgets/movie INSTALLS += target sources + +wince*: { + addFiles.sources += *.mng + addFiles.path = . + DEPLOYMENT += addFiles + DEPLOYMENT_PLUGIN += qmng +} + -- cgit v0.12 From ac2ea04e516fa7818cb7b4dbe7dd2619cec9fbda Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 25 May 2009 17:02:09 +0200 Subject: Some refactoring of windows specific code + a private class of animations --- src/corelib/animation/qabstractanimation.cpp | 26 ----------------- src/corelib/animation/qabstractanimation_p.h | 24 ++++++++++++---- src/corelib/kernel/qcoreapplication_win.cpp | 31 ++++++++++++++------ src/corelib/kernel/qeventdispatcher_win.cpp | 7 ----- src/corelib/tools/qbytearray.cpp | 2 +- src/corelib/tools/qlocale.cpp | 4 +-- src/gui/kernel/qapplication_win.cpp | 42 ++++++++-------------------- src/gui/kernel/qwindowdefs_win.h | 2 +- 8 files changed, 56 insertions(+), 82 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 94a94d1..16307e6 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -188,32 +188,6 @@ void QUnifiedTimer::updateRecentlyStartedAnimations() animationsToStart.clear(); } -/* - defines the timing interval. Default is DEFAULT_TIMER_INTERVAL -*/ -void QUnifiedTimer::setTimingInterval(int interval) -{ - timingInterval = interval; - if (animationTimer.isActive()) { - //we changed the timing interval - animationTimer.start(timingInterval, this); - } -} - -/* - this allows to have a consistent timer interval at each tick from the timer - not taking the real time that passed into account. -*/ -void QUnifiedTimer::setConsistentTiming(bool b) -{ - consistentTiming = b; -} - -int QUnifiedTimer::elapsedTime() const -{ - return lastTick; -} - void QUnifiedTimer::timerEvent(QTimerEvent *event) { //this is simply the time we last received a tick diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index e64554c..7a4bfcf 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -101,21 +101,35 @@ private: }; -class Q_CORE_EXPORT QUnifiedTimer : public QObject +class QUnifiedTimer : public QObject { private: QUnifiedTimer(); public: - static QUnifiedTimer *instance(); + //XXX this is needed by dui + static Q_CORE_EXPORT QUnifiedTimer *instance(); void registerAnimation(QAbstractAnimation *animation); void unregisterAnimation(QAbstractAnimation *animation); - void setTimingInterval(int interval); - void setConsistentTiming(bool consistent); + //defines the timing interval. Default is DEFAULT_TIMER_INTERVAL + void setTimingInterval(int interval) + { + timingInterval = interval; + if (animationTimer.isActive()) { + //we changed the timing interval + animationTimer.start(timingInterval, this); + } + } + + /* + this allows to have a consistent timer interval at each tick from the timer + not taking the real time that passed into account. + */ + void setConsistentTiming(bool consistent) { consistentTiming = consistent; } - int elapsedTime() const; + int elapsedTime() const { return lastTick; } protected: void timerEvent(QTimerEvent *); diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 7ab91c9..9868c23 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -51,12 +51,11 @@ QT_BEGIN_NAMESPACE -// ############### DON'T EXPORT HERE!!! -Q_CORE_EXPORT char appFileName[MAX_PATH+1]; // application file name -Q_CORE_EXPORT char theAppName[MAX_PATH+1]; // application name -Q_CORE_EXPORT HINSTANCE appInst = 0; // handle to app instance -Q_CORE_EXPORT HINSTANCE appPrevInst = 0; // handle to prev app instance -Q_CORE_EXPORT int appCmdShow = 0; +char appFileName[MAX_PATH+1]; // application file name +char theAppName[MAX_PATH+1]; // application name +HINSTANCE appInst = 0; // handle to app instance +HINSTANCE appPrevInst = 0; // handle to prev app instance +int appCmdShow = 0; bool usingWinMain = false; // whether the qWinMain() is used or not Q_CORE_EXPORT HINSTANCE qWinAppInst() // get Windows app handle @@ -69,6 +68,12 @@ Q_CORE_EXPORT HINSTANCE qWinAppPrevInst() // get Windows prev app return appPrevInst; } +Q_CORE_EXPORT int qWinAppCmdShow() // get main window show command +{ + return appCmdShow; +} + + void set_winapp_name() { static bool already_set = false; @@ -89,6 +94,14 @@ void set_winapp_name() int l = qstrlen(theAppName); if ((l > 4) && !qstricmp(theAppName + l - 4, ".exe")) theAppName[l-4] = '\0'; // drop .exe extension + + if (appInst == 0) { + QT_WA({ + appInst = GetModuleHandle(0); + }, { + appInst = GetModuleHandleA(0); + }); + } } } @@ -173,14 +186,14 @@ void qWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam, // Create command line - set_winapp_name(); - argv = qWinCmdLine(cmdParam, int(strlen(cmdParam)), argc); // Get Windows parameters appInst = instance; appPrevInst = prevInstance; appCmdShow = cmdShow; + + set_winapp_name(); } /*! @@ -618,7 +631,7 @@ QString valueCheck(uint actual, ...) #ifdef Q_CC_BOR -Q_CORE_EXPORT QString decodeMSG(const MSG& msg) +QString decodeMSG(const MSG& msg) { return QString::fromLatin1("THis is not supported on Borland"); } diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index c4061f4..2dd5534 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -396,13 +396,6 @@ Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa { return PostMessageA(hWnd, msg, wParam, lParam); }); } -Q_CORE_EXPORT bool winGetMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin, - UINT wMsgFilterMax) -{ - QT_WA({ return GetMessage(msg, hWnd, wMsgFilterMin, wMsgFilterMax); } , - { return GetMessageA(msg, hWnd, wMsgFilterMin, wMsgFilterMax); }); -} - // This function is called by a workerthread void WINAPI CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/, DWORD_PTR user, DWORD_PTR /*reserved*/, DWORD_PTR /*reserved*/) { diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 6aa35f3..49dd52d 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -579,7 +579,7 @@ static inline char qToLower(char c) return c; } -Q_CORE_EXPORT QByteArray::Data QByteArray::shared_null = {Q_BASIC_ATOMIC_INITIALIZER(1), +QByteArray::Data QByteArray::shared_null = {Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, shared_null.array, {0} }; QByteArray::Data QByteArray::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, shared_empty.array, {0} }; diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 23c6ffb..248137a 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -120,7 +120,7 @@ static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, Q_CORE_EXPORT char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str); Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); -Q_CORE_EXPORT qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok); +static qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok); static qulonglong qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok); /****************************************************************************** @@ -4671,7 +4671,7 @@ static qulonglong qstrtoull(const char *nptr, const char **endptr, register int * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ -Q_CORE_EXPORT qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok) +static qlonglong qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok) { register const char *s; register qulonglong acc; diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 6237657..77625de 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -376,11 +376,6 @@ QRgb qt_colorref2qrgb(COLORREF col) Internal variables and functions *****************************************************************************/ -extern Q_CORE_EXPORT char theAppName[]; -extern Q_CORE_EXPORT char appFileName[]; -extern Q_CORE_EXPORT HINSTANCE appInst; // handle to app instance -extern Q_CORE_EXPORT HINSTANCE appPrevInst; // handle to prev app instance -extern Q_CORE_EXPORT int appCmdShow; // main window show command static HWND curWin = 0; // current window static HDC displayDC = 0; // display device context @@ -752,20 +747,11 @@ void qt_init(QApplicationPrivate *priv, int) priv->argc = j; } - // Get the application name/instance if qWinMain() was not invoked #ifndef Q_WS_WINCE // No message boxes but important ones SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); #endif - if (appInst == 0) { - QT_WA({ - appInst = GetModuleHandle(0); - }, { - appInst = GetModuleHandleA(0); - }); - } - #ifndef Q_WS_WINCE // Initialize OLE/COM // S_OK means success and S_FALSE means that it has already @@ -790,7 +776,7 @@ void qt_init(QApplicationPrivate *priv, int) #ifndef QT_NO_CURSOR QCursorData::initialize(); #endif - qApp->setObjectName(QLatin1String(theAppName)); + qApp->setObjectName(priv->appName()); #if !defined(Q_WS_WINCE) // default font @@ -888,12 +874,6 @@ void qt_cleanup() Platform specific global and internal functions *****************************************************************************/ -Q_GUI_EXPORT int qWinAppCmdShow() // get main window show command -{ - return appCmdShow; -} - - Q_GUI_EXPORT HDC qt_win_display_dc() // get display DC { Q_ASSERT(qApp && qApp->thread() == QThread::currentThread()); @@ -989,11 +969,11 @@ const QString qt_reg_winclass(QWidget *w) // register window class if (classExists == -1) { QT_WA({ WNDCLASS wcinfo; - classExists = GetClassInfo((HINSTANCE)qWinAppInst(), (TCHAR*)cname.utf16(), &wcinfo); + classExists = GetClassInfo(qWinAppInst(), (TCHAR*)cname.utf16(), &wcinfo); classExists = classExists && wcinfo.lpfnWndProc != QtWndProc; }, { WNDCLASSA wcinfo; - classExists = GetClassInfoA((HINSTANCE)qWinAppInst(), cname.toLatin1(), &wcinfo); + classExists = GetClassInfoA(qWinAppInst(), cname.toLatin1(), &wcinfo); classExists = classExists && wcinfo.lpfnWndProc != QtWndProc; }); } @@ -1013,9 +993,9 @@ const QString qt_reg_winclass(QWidget *w) // register window class wc.lpfnWndProc = (WNDPROC)QtWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = (HINSTANCE)qWinAppInst(); + wc.hInstance = qWinAppInst(); if (icon) { - wc.hIcon = LoadIcon(appInst, L"IDI_ICON1"); + wc.hIcon = LoadIcon(qWinAppInst(), L"IDI_ICON1"); if (!wc.hIcon) wc.hIcon = LoadIcon(0, IDI_APPLICATION); } else { @@ -1032,9 +1012,9 @@ const QString qt_reg_winclass(QWidget *w) // register window class wc.lpfnWndProc = (WNDPROC)QtWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = (HINSTANCE)qWinAppInst(); + wc.hInstance = qWinAppInst(); if (icon) { - wc.hIcon = LoadIconA(appInst, (char*)"IDI_ICON1"); + wc.hIcon = LoadIconA(qWinAppInst(), (char*)"IDI_ICON1"); if (!wc.hIcon) wc.hIcon = LoadIconA(0, (char*)IDI_APPLICATION); } else { @@ -1053,9 +1033,9 @@ const QString qt_reg_winclass(QWidget *w) // register window class wc.lpfnWndProc = (WNDPROC)QtWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = (HINSTANCE)qWinAppInst(); + wc.hInstance = qWinAppInst(); if (icon) { - wc.hIcon = LoadIcon(appInst, L"IDI_ICON1"); + wc.hIcon = LoadIcon(qWinAppInst(), L"IDI_ICON1"); // if (!wc.hIcon) // wc.hIcon = LoadIcon(0, IDI_APPLICATION); } else { @@ -1089,9 +1069,9 @@ static void unregWinClasses() QHash::ConstIterator it = hash->constBegin(); while (it != hash->constEnd()) { QT_WA({ - UnregisterClass((TCHAR*)it.key().utf16(), (HINSTANCE)qWinAppInst()); + UnregisterClass((TCHAR*)it.key().utf16(), qWinAppInst()); } , { - UnregisterClassA(it.key().toLatin1(), (HINSTANCE)qWinAppInst()); + UnregisterClassA(it.key().toLatin1(), qWinAppInst()); }); ++it; } diff --git a/src/gui/kernel/qwindowdefs_win.h b/src/gui/kernel/qwindowdefs_win.h index 3899c23..a24afd4 100644 --- a/src/gui/kernel/qwindowdefs_win.h +++ b/src/gui/kernel/qwindowdefs_win.h @@ -122,7 +122,7 @@ QT_BEGIN_NAMESPACE Q_CORE_EXPORT HINSTANCE qWinAppInst(); Q_CORE_EXPORT HINSTANCE qWinAppPrevInst(); -Q_GUI_EXPORT int qWinAppCmdShow(); +Q_CORE_EXPORT int qWinAppCmdShow(); Q_GUI_EXPORT HDC qt_win_display_dc(); QT_END_NAMESPACE -- cgit v0.12 From 7dbc1327c513823631986ecaea9b2bae8efc53fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Mon, 25 May 2009 17:20:06 +0200 Subject: Fixed insertion of unnecessary spaces at the end of attribute lists Also makes QDomDocument::toString() consistent with QXmlStreamWriter and xmlTextWriter from libxml2. Reviewed-by: Thiago Macieira --- src/xml/dom/qdom.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 550abc9..dc6ff92 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -2694,7 +2694,7 @@ void QDomNode::save(QTextStream& str, int indent) const If the document contains invalid XML characters or characters that cannot be encoded in the given encoding, the result and behavior is undefined. - \since 4.2 + \since 4.2 */ void QDomNode::save(QTextStream& str, int indent, EncodingPolicy encodingPolicy) const { @@ -4597,9 +4597,9 @@ void QDomElementPrivate::save(QTextStream& s, int depth, int indent) const /* Write out attributes. */ if (!m_attr->map.isEmpty()) { - s << ' '; QHash::const_iterator it = m_attr->map.constBegin(); for (; it != m_attr->map.constEnd(); ++it) { + s << ' '; if (it.value()->namespaceURI.isNull()) { s << it.value()->name << "=\"" << encodeText(it.value()->value, s, true, true) << '\"'; } else { @@ -4622,7 +4622,6 @@ void QDomElementPrivate::save(QTextStream& s, int depth, int indent) const outputtedPrefixes.insert(it.value()->prefix); } } - s << ' '; } } -- cgit v0.12 From a731cb5c1765bc3ab71469e86ec0533e5a5c18a5 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 25 May 2009 17:40:35 +0200 Subject: don't build examples/qtconcurrent/qtconcurrent.pro by default on Win CE This examples doesn't make much sense on most Windows CE devices. Task-number: 254433 Reviewed-by: mauricek BT: yes --- examples/qtconcurrent/qtconcurrent.pro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/qtconcurrent/qtconcurrent.pro b/examples/qtconcurrent/qtconcurrent.pro index 53008f0..5d73533 100644 --- a/examples/qtconcurrent/qtconcurrent.pro +++ b/examples/qtconcurrent/qtconcurrent.pro @@ -1,10 +1,13 @@ TEMPLATE = subdirs SUBDIRS = imagescaling \ map \ - progressdialog \ runfunction \ wordcount +!wince* { + SUBDIRS += progressdialog +} + # install target.path = $$[QT_INSTALL_EXAMPLES]/qtconcurrent sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS qtconcurrent.pro README -- cgit v0.12 From 81a387e7a7136545db39dc536dee739c67c94e6f Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 25 May 2009 18:03:18 +0200 Subject: Fix all docs warnings and add since 4.6 to new methods Reviewed-by:TrustMe --- src/gui/image/qpixmapcache.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 31d29d6..3cfc191 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -128,6 +128,11 @@ bool QPixmapCache::Key::operator ==(const Key &key) const } /*! + \fn bool QPixmapCache::Key::operator !=(const Key &key) const + \internal +*/ + +/*! \internal */ QPixmapCache::Key &QPixmapCache::Key::operator =(const Key &other) @@ -431,8 +436,10 @@ bool QPixmapCache::find(const QString &key, QPixmap& pixmap) /*! Looks for a cached pixmap associated with the \a key in the cache. - If the pixmap is found, the function sets \a pm to that pixmap and - returns true; otherwise it leaves \a pm alone and returns false. + If the pixmap is found, the function sets \a pixmap to that pixmap and + returns true; otherwise it leaves \a pixmap alone and returns false. + + \since 4.6 Example: \snippet doc/src/snippets/code/src_gui_image_qpixmapcache.cpp 1 @@ -448,10 +455,12 @@ bool QPixmapCache::find(const QString &key, QPixmap* pixmap) /*! Looks for a cached pixmap associated with the \a key in the cache. - If the pixmap is found, the function sets \a pm to that pixmap and - returns true; otherwise it leaves \a pm alone and returns false. If + If the pixmap is found, the function sets \a pixmap to that pixmap and + returns true; otherwise it leaves \a pixmap alone and returns false. If the pixmap is not found, it means that the \a key is not valid anymore, so it will be released for the next insertion. + + \since 4.6 */ bool QPixmapCache::find(const Key &key, QPixmap* pixmap) { @@ -465,7 +474,7 @@ bool QPixmapCache::find(const Key &key, QPixmap* pixmap) } /*! - Inserts a copy of the pixmap \a pm associated with the \a key into + Inserts a copy of the pixmap \a pixmap associated with the \a key into the cache. All pixmaps inserted by the Qt library have a key starting with @@ -490,7 +499,7 @@ bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap) } /*! - Inserts a copy of the pixmap \a pm into + Inserts a copy of the pixmap \a pixmap into the cache and return you the key. When a pixmap is inserted and the cache is about to exceed its @@ -501,6 +510,8 @@ bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap) deleted when more space is needed. \sa setCacheLimit(), replace() + + \since 4.6 */ QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap) { @@ -509,10 +520,12 @@ QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap) /*! Replace the pixmap associated to the \a key into - the cache. It return true if the pixmap \a pm has been correctly + the cache. It return true if the pixmap \a pixmap has been correctly inserted into the cache false otherwise. \sa setCacheLimit(), insert() + + \since 4.6 */ bool QPixmapCache::replace(const Key &key, const QPixmap &pixmap) { @@ -562,6 +575,8 @@ void QPixmapCache::remove(const QString &key) /*! Removes the pixmap associated with \a key from the cache and release the key for a future insertion. + + \since 4.6 */ void QPixmapCache::remove(const Key &key) { -- cgit v0.12 From 305ce9ea67c11826d91c032ead55edfd5e15462f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 25 May 2009 18:10:08 +0200 Subject: fix warning in QtSvg if qreal == float Reviewed-by: mauricek --- src/svg/qsvggenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index e822da5..fd4c875 100644 --- a/src/svg/qsvggenerator.cpp +++ b/src/svg/qsvggenerator.cpp @@ -261,7 +261,7 @@ public: constantAlpha &= (stops.at(i).second.alpha() == alpha); if (!constantAlpha) { - const qreal spacing = 0.02; + const qreal spacing = qreal(0.02); QGradientStops newStops; QRgb fromColor = PREMUL(stops.at(0).second.rgba()); QRgb toColor; -- cgit v0.12 From 3868c7dacde57c3e929ad72b9c9c42f8ddf4dc62 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 25 May 2009 18:42:16 +0200 Subject: BT: Namespace compile fixes. This broke again. I Need to get a way to automate this, I'll discuss with QA. --- src/gui/kernel/qcocoaapplicationdelegate_mac.mm | 2 +- src/gui/kernel/qcocoaview_mac_p.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index 9a24645..2ca6a3d 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -90,6 +90,7 @@ QT_BEGIN_NAMESPACE extern void onApplicationChangedActivation(bool); // qapplication_mac.mm +extern void qt_release_apple_event_handler(); //qapplication_mac.mm QT_END_NAMESPACE QT_FORWARD_DECLARE_CLASS(QDesktopWidgetImplementation) @@ -207,7 +208,6 @@ static void cleanupCocoaApplicationDelegate() { Q_UNUSED(aNotification); inLaunch = false; - extern void qt_release_apple_event_handler(); //qapplication_mac.mm qt_release_apple_event_handler(); } diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index 983c762..527b1a6 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -59,6 +59,7 @@ QT_FORWARD_DECLARE_CLASS(QWidgetPrivate); QT_FORWARD_DECLARE_CLASS(QWidget); QT_FORWARD_DECLARE_CLASS(QEvent); QT_FORWARD_DECLARE_CLASS(QCocoaDropData); +QT_FORWARD_DECLARE_CLASS(QStringList); QT_BEGIN_NAMESPACE struct DnDParams -- cgit v0.12 From b94416a8fe3fae0e9ab01dea9d5a78a21c4affc0 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 25 May 2009 19:43:12 +0200 Subject: Doc: Fixed terminology. Reviewed-by: Trust Me --- src/corelib/tools/qcryptographichash.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index 7232626..e438179 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -74,7 +74,7 @@ public: QCryptographicHash can be used to generate cryptographic hashes of binary or text data. - Currently MD4, MD5, and SHA1 are supported. + Currently MD4, MD5, and SHA-1 are supported. */ /*! -- cgit v0.12 From 4bee6cac20b52761f39b139c61d5861fe7b68c6f Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 25 May 2009 19:52:30 +0200 Subject: Doc: Fixed links to resources on the qtsoftware.com Web site. Task-number: 254463 Reviewed-by: Denis Dzyubenko --- doc/src/index.qdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index 4ead9e4..5bf3661 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -207,10 +207,10 @@ -- cgit v0.12 From 152d5fb2d97432d92b6b84e6e81c0236d278ac5d Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 25 May 2009 20:00:12 +0200 Subject: Doc: Removed documentation about the non-existent QKeyEvent::standardKey() function. Task-number: 254074 Reviewed-by: Trust Me --- src/gui/kernel/qkeysequence.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 352d26a..3bcf9e3 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -629,8 +629,6 @@ const uint QKeySequencePrivate::numberOfKeyBindings = sizeof(QKeySequencePrivate This enum represent standard key bindings. They can be used to assign platform dependent keyboard shortcuts to a QAction. - QKeyEvent also provides the function QKeyEvent::standardKey() to - query if it matches an existing key binding. Note that the key bindings are platform dependent. The currently bound shortcuts can be queried using keyBindings(). -- cgit v0.12 From 675e9e645fb596ae822fb10093bea25a47a78488 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 25 May 2009 19:54:31 +0200 Subject: remove now unused static function sneak in white space change :) --- tools/linguist/lupdate/java.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/tools/linguist/lupdate/java.cpp b/tools/linguist/lupdate/java.cpp index 31024f9..658aebf 100644 --- a/tools/linguist/lupdate/java.cpp +++ b/tools/linguist/lupdate/java.cpp @@ -375,22 +375,13 @@ static bool matchString( QString &s ) return true; } -static bool matchInteger( qlonglong *number) -{ - bool matches = (yyTok == Tok_Integer); - if (matches) { - yyTok = getToken(); - *number = yyInteger; - } - return matches; -} - static bool matchStringOrNull(QString &s) { bool matches = matchString(s); if (!matches) { matches = (yyTok == Tok_null); - if (matches) yyTok = getToken(); + if (matches) + yyTok = getToken(); } return matches; } -- cgit v0.12 From ef4c47d8b4dc9b2056541cd29686b0959fd778a4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 25 May 2009 19:56:39 +0200 Subject: implement --no-ui-lines option (complementing lupdate) --- tools/linguist/lconvert/main.cpp | 7 +++++++ tools/linguist/shared/translator.cpp | 20 ++++++++++++++++++++ tools/linguist/shared/translator.h | 1 + 3 files changed, 28 insertions(+) diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp index bdc6c9a..52bf91f 100644 --- a/tools/linguist/lconvert/main.cpp +++ b/tools/linguist/lconvert/main.cpp @@ -97,6 +97,8 @@ static int usage(const QStringList &args) " Drop obsolete messages.\n\n" " --no-finished\n" " Drop finished messages.\n\n" + " --no-ui-lines\n" + " Drop line numbers from references to .ui files.\n\n" " --verbose\n" " be a bit more verbose\n\n" "Long options can be specified with only one leading dash, too.\n\n" @@ -129,6 +131,7 @@ int main(int argc, char *argv[]) bool noObsolete = false; bool noFinished = false; bool verbose = false; + bool noUiLines = false; ConversionData cd; Translator tr; @@ -180,6 +183,8 @@ int main(int argc, char *argv[]) noObsolete = true; } else if (args[i] == QLatin1String("-no-finished")) { noFinished = true; + } else if (args[i] == QLatin1String("-no-ui-lines")) { + noUiLines = true; } else if (args[i] == QLatin1String("-verbose")) { verbose = true; } else if (args[i].startsWith(QLatin1Char('-'))) { @@ -224,6 +229,8 @@ int main(int argc, char *argv[]) tr.stripFinishedMessages(); if (dropTranslations) tr.dropTranslations(); + if (noUiLines) + tr.dropUiLines(); if (!tr.save(outFileName, cd, outFormat)) { qWarning("%s", qPrintable(cd.error())); diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp index 312bb71..c1f242d 100644 --- a/tools/linguist/shared/translator.cpp +++ b/tools/linguist/shared/translator.cpp @@ -416,6 +416,26 @@ void Translator::dropTranslations() } } +void Translator::dropUiLines() +{ + QString uiXt = QLatin1String(".ui"); + QString juiXt = QLatin1String(".jui"); + for (TMM::Iterator it = m_messages.begin(); it != m_messages.end(); ++it) { + QHash have; + QList refs; + foreach (const TranslatorMessage::Reference &itref, it->allReferences()) { + const QString &fn = itref.fileName(); + if (fn.endsWith(uiXt) || fn.endsWith(juiXt)) { + if (++have[fn] == 1) + refs.append(TranslatorMessage::Reference(fn, -1)); + } else { + refs.append(itref); + } + } + it->setReferences(refs); + } +} + QSet Translator::resolveDuplicates() { QSet dups; diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index 4e97000..3dda41a 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -132,6 +132,7 @@ public: void stripNonPluralForms(); void stripIdenticalSourceTranslations(); void dropTranslations(); + void dropUiLines(); void makeFileNamesAbsolute(const QDir &originalPath); QSet resolveDuplicates(); static void reportDuplicates(const QSet &dupes, -- cgit v0.12 From afcd5b98b1855390e1c5c1308f0beff256391d96 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 25 May 2009 19:58:02 +0200 Subject: implement --locations option (complementing lupdate) --- tools/linguist/lconvert/main.cpp | 17 +++++++++++++++++ tools/linguist/shared/translator.h | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp index 52bf91f..ce17b6f 100644 --- a/tools/linguist/lconvert/main.cpp +++ b/tools/linguist/lconvert/main.cpp @@ -97,6 +97,9 @@ static int usage(const QStringList &args) " Drop obsolete messages.\n\n" " --no-finished\n" " Drop finished messages.\n\n" + " --locations {absolute|relative|none}\n" + " Override how source code references are saved in ts files.\n" + " Default is absolute.\n}n" " --no-ui-lines\n" " Drop line numbers from references to .ui files.\n\n" " --verbose\n" @@ -132,6 +135,7 @@ int main(int argc, char *argv[]) bool noFinished = false; bool verbose = false; bool noUiLines = false; + Translator::LocationsType locations = Translator::DefaultLocations; ConversionData cd; Translator tr; @@ -183,6 +187,17 @@ int main(int argc, char *argv[]) noObsolete = true; } else if (args[i] == QLatin1String("-no-finished")) { noFinished = true; + } else if (args[i] == QLatin1String("-locations")) { + if (++i >= args.size()) + return usage(args); + if (args[i] == QLatin1String("none")) + locations = Translator::NoLocations; + else if (args[i] == QLatin1String("relative")) + locations = Translator::RelativeLocations; + else if (args[i] == QLatin1String("absolute")) + locations = Translator::AbsoluteLocations; + else + return usage(args); } else if (args[i] == QLatin1String("-no-ui-lines")) { noUiLines = true; } else if (args[i] == QLatin1String("-verbose")) { @@ -231,6 +246,8 @@ int main(int argc, char *argv[]) tr.dropTranslations(); if (noUiLines) tr.dropUiLines(); + if (locations != Translator::DefaultLocations) + tr.setLocationsType(locations); if (!tr.save(outFileName, cd, outFormat)) { qWarning("%s", qPrintable(cd.error())); diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index 3dda41a..5d0549b 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -144,7 +144,7 @@ public: QString languageCode() const { return m_language; } QString sourceLanguageCode() const { return m_sourceLanguage; } - enum LocationsType { NoLocations, RelativeLocations, AbsoluteLocations }; + enum LocationsType { DefaultLocations, NoLocations, RelativeLocations, AbsoluteLocations }; void setLocationsType(LocationsType lt) { m_locationsType = lt; } LocationsType locationsType() const { return m_locationsType; } -- cgit v0.12 From 8b34bd541c6aa201c4d872210228bce8217a5e03 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 25 May 2009 20:10:25 +0200 Subject: Doc: Miscellaneous documentation fixes for Qt 4.5.x and later. Reviewed-by: Trust Me --- doc/src/snippets/picture/picture.cpp | 2 +- src/corelib/tools/qstringlist.cpp | 2 -- src/gui/painting/qpainterpath.cpp | 8 ++++---- src/gui/text/qfontmetrics.cpp | 12 ++++++------ src/network/ssl/qsslcertificate.cpp | 2 +- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/doc/src/snippets/picture/picture.cpp b/doc/src/snippets/picture/picture.cpp index 07cedbf..be171c6 100644 --- a/doc/src/snippets/picture/picture.cpp +++ b/doc/src/snippets/picture/picture.cpp @@ -66,7 +66,7 @@ int main() QPicture picture; picture.load("drawing.pic"); // load picture QPainter painter; - painter.begin(&myWidget); // paint in myWidget + painter.begin(&myImage); // paint in myImage painter.drawPicture(0, 0, picture); // draw the picture at (0,0) painter.end(); // painting done //! [1] diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp index e22f122..cf1bff8 100644 --- a/src/corelib/tools/qstringlist.cpp +++ b/src/corelib/tools/qstringlist.cpp @@ -621,8 +621,6 @@ int QtPrivate::QStringList_lastIndexOf(const QStringList *that, QRegExp &rx, int the list, searching forward from index position \a from. Returns -1 if no item matched. - By default, this function is case sensitive. - \sa lastIndexOf(), contains(), QList::indexOf() */ diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 9ce16d3..1b2c4e3 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -2695,7 +2695,7 @@ qreal QPainterPath::length() const /*! Returns percentage of the whole path at the specified length \a len. - Note that similarly to other percent methods, the percentage measurment + Note that similarly to other percent methods, the percentage measurement is not linear with regards to the length, if curves are present in the path. When curves are present the percentage argument is mapped to the t parameter of the Bezier equations. @@ -2812,7 +2812,7 @@ static inline QBezier bezierAtT(const QPainterPath &path, qreal t, qreal *starti Returns the point at at the percentage \a t of the current path. The argument \a t has to be between 0 and 1. - Note that similarly to other percent methods, the percentage measurment + Note that similarly to other percent methods, the percentage measurement is not linear with regards to the length, if curves are present in the path. When curves are present the percentage argument is mapped to the t parameter of the Bezier equations. @@ -2843,7 +2843,7 @@ QPointF QPainterPath::pointAtPercent(qreal t) const Positive values for the angles mean counter-clockwise while negative values mean the clockwise direction. Zero degrees is at the 3 o'clock position. - Note that similarly to the other percent methods, the percentage measurment + Note that similarly to the other percent methods, the percentage measurement is not linear with regards to the length if curves are present in the path. When curves are present the percentage argument is mapped to the t parameter of the Bezier equations. @@ -2875,7 +2875,7 @@ qreal QPainterPath::angleAtPercent(qreal t) const Returns the slope of the path at the percentage \a t. The argument \a t has to be between 0 and 1. - Note that similarly to other percent methods, the percentage measurment + Note that similarly to other percent methods, the percentage measurement is not linear with regards to the length, if curves are present in the path. When curves are present the percentage argument is mapped to the t parameter of the Bezier equations. diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 88d0610..87da628 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -670,8 +670,8 @@ QRect QFontMetrics::boundingRect(const QString &text) const Returns the rectangle that is covered by ink if character \a ch were to be drawn at the origin of the coordinate system. - Note that the bounding rectangle may extend to the left of (0, 0), - e.g. for italicized fonts, and that the text output may cover \e + Note that the bounding rectangle may extend to the left of (0, 0) + (e.g., for italicized fonts), and that the text output may cover \e all pixels in the bounding rectangle. For a space character the rectangle will usually be empty. @@ -724,7 +724,7 @@ QRect QFontMetrics::boundingRect(QChar ch) const \o Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter}) \o Qt::TextSingleLine ignores newline characters in the text. \o Qt::TextExpandTabs expands tabs (see below) - \o Qt::TextShowMnemonic interprets "&x" as \underline{x}, i.e. underlined. + \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. \o Qt::TextWordWrap breaks the text to fit the rectangle. \endlist @@ -781,7 +781,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te \list \o Qt::TextSingleLine ignores newline characters. \o Qt::TextExpandTabs expands tabs (see below) - \o Qt::TextShowMnemonic interprets "&x" as \underline{x}, i.e. underlined. + \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. \o Qt::TextWordBreak breaks the text to fit the rectangle. \endlist @@ -1500,7 +1500,7 @@ QRectF QFontMetricsF::boundingRect(QChar ch) const \o Qt::AlignCenter (== \c{Qt::AlignHCenter | Qt::AlignVCenter}) \o Qt::TextSingleLine ignores newline characters in the text. \o Qt::TextExpandTabs expands tabs (see below) - \o Qt::TextShowMnemonic interprets "&x" as \underline{x}, i.e. underlined. + \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. \o Qt::TextWordWrap breaks the text to fit the rectangle. \endlist @@ -1559,7 +1559,7 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& \list \o Qt::TextSingleLine ignores newline characters. \o Qt::TextExpandTabs expands tabs (see below) - \o Qt::TextShowMnemonic interprets "&x" as \underline{x}, i.e. underlined. + \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined. \o Qt::TextWordBreak breaks the text to fit the rectangle. \endlist diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index a2ba644..7b554dc 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -267,7 +267,7 @@ QByteArray QSslCertificate::serialNumber() const /*! Returns a cryptographic digest of this certificate. By default, - and MD5 digest will be generated, but you can also specify a + an MD5 digest will be generated, but you can also specify a custom \a algorithm. */ QByteArray QSslCertificate::digest(QCryptographicHash::Algorithm algorithm) const -- cgit v0.12 From 23820c30052ea23ecf2226c300fc4819dd294306 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 25 May 2009 20:13:34 +0200 Subject: Doc: Fixed custom graphics item snippet. As reported on qt-interest: http://lists.trolltech.com/pipermail/qt-interest/2009-May/007036.html Reviewed-by: Trust Me --- doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp b/doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp index a57de9d..d9e38ed 100644 --- a/doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp +++ b/doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp @@ -6,7 +6,7 @@ public: { qreal penWidth = 1; return QRectF(-10 - penWidth / 2, -10 - penWidth / 2, - 20 + penWidth / 2, 20 + penWidth / 2); + 20 + penWidth, 20 + penWidth); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, -- cgit v0.12 From bbefe9e67366151e2286a2ff6bee0d1009b2a12c Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 25 May 2009 20:24:22 +0200 Subject: Doc: Removed the incorrect figures for Thumb builds of libraries. We need to resolve the issues around the use of Thumb code in Qt and automate the building and comparison of libraries. Reviewed-by: Trust Me --- doc/src/installation.qdoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/src/installation.qdoc b/doc/src/installation.qdoc index 925a195..6a689f9 100644 --- a/doc/src/installation.qdoc +++ b/doc/src/installation.qdoc @@ -738,8 +738,6 @@ in the \l{Qt for Windows CE Requirements} document. \header \o Minimal \o Normal \o Minimal \o Normal \o Minimal \o Normal \o Minimal \o Normal \row \o linux-x86-g++ \o GCC 4.2.4 \o 1.7M \o 2.7M \o 3.3M \o 9.9M \o 653K \o 1.1M \o N/A \o 17M \row \o linux-arm-g++ \o GCC 4.1.1 \o 1.9M \o 3.2M \o 4.1M \o 11M \o 507K \o 1.0M \o N/A \o 17M - \row \o linux-arm-g++ (thumb) - \o GCC 4.1.1 \o 1.7M \o 2.8M \o 4.0M \o 9.8M \o 409K \o 796K \o N/A \o 17M \row \o linux-mips-g++ (MIPS32) \o GCC 4.2.4 \o 2.0M \o 3.2M \o 4.5M \o 12M \o 505K \o 1003K \o N/A \o 21M \endtable -- cgit v0.12 From a4ca38bab521e1f0095b9c90c4623ca9d41d219b Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 25 May 2009 20:27:19 +0200 Subject: Doc: Clarified what close(), abort() and disconnectFromHost() really do to the socket connection. (Reviewed - see below.) Also included corrections to the description of how to send SocketError and SocketState values via signals. (Trust me - as part of an earlier revision of the custom types documentation.) Task-number: 222907 Reviewed-by: Andy Shaw --- src/network/socket/qabstractsocket.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 336a7e7..4bb12e6 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -99,7 +99,7 @@ the client has read the data). Note that Qt does not limit the write buffer size. You can monitor its size by listening to this signal. - + The readyRead() signal is emitted every time a new chunk of data has arrived. bytesAvailable() then returns the number of bytes that are available for reading. Typically, you would connect the @@ -199,9 +199,10 @@ parameter describes the type of error that occurred. QAbstractSocket::SocketError is not a registered metatype, so for queued - connections, you will have to register it with Q_REGISTER_METATYPE. + connections, you will have to register it with Q_DECLARE_METATYPE() and + qRegisterMetaType(). - \sa error(), errorString() + \sa error(), errorString(), {Creating Custom Qt Types} */ /*! @@ -211,9 +212,10 @@ The \a socketState parameter is the new state. QAbstractSocket::SocketState is not a registered metatype, so for queued - connections, you will have to register it with Q_REGISTER_METATYPE. + connections, you will have to register it with Q_REGISTER_METATYPE() and + qRegisterMetaType(). - \sa state() + \sa state(), {Creating Custom Qt Types} */ /*! @@ -1864,9 +1866,9 @@ bool QAbstractSocket::waitForDisconnected(int msecs) } /*! - Aborts the current connection and resets the socket. Unlike - disconnectFromHost(), this function immediately closes the socket, discarding - any pending data in the write buffer. + Aborts the current connection and resets the socket. Unlike disconnectFromHost(), + this function immediately closes the socket, discarding any pending data in the + write buffer. \sa disconnectFromHost(), close() */ @@ -2163,7 +2165,12 @@ void QAbstractSocket::setPeerName(const QString &name) } /*! - Disconnects the socket's connection with the host. + Closes the I/O device for the socket, disconnects the socket's connection with the + host, closes the socket, and resets the name, address, port number and underlying + socket descriptor. + + See QIODevice::close() for a description of the actions that occur when an I/O + device is closed. \sa abort() */ @@ -2456,7 +2463,8 @@ QNetworkProxy QAbstractSocket::proxy() const #endif // QT_NO_NETWORKPROXY #ifdef QT3_SUPPORT -/*! \enum QAbstractSocket::Error +/*! + \enum QAbstractSocket::Error \compat Use QAbstractSocket::SocketError instead. -- cgit v0.12 From f8cb8f242817c94a3f368b01243a88918d211f1e Mon Sep 17 00:00:00 2001 From: Ian Walters Date: Tue, 26 May 2009 09:50:16 +1000 Subject: Protect dump function by ifdef. Use the same pattern for protecting the dump function as qmap.h and qhash.h employ. --- src/corelib/tools/qcontiguouscache.cpp | 4 ++++ src/corelib/tools/qcontiguouscache.h | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qcontiguouscache.cpp b/src/corelib/tools/qcontiguouscache.cpp index 7db3a5a..996ac18 100644 --- a/src/corelib/tools/qcontiguouscache.cpp +++ b/src/corelib/tools/qcontiguouscache.cpp @@ -40,10 +40,13 @@ ****************************************************************************/ #include "qcontiguouscache.h" +#ifdef QT_QCONTIGUOUSCACHE_DEBUG #include +#endif QT_BEGIN_NAMESPACE +#ifdef QT_QCONTIGUOUSCACHE_DEBUG void QContiguousCacheData::dump() const { qDebug() << "capacity:" << alloc; @@ -51,6 +54,7 @@ void QContiguousCacheData::dump() const qDebug() << "start:" << start; qDebug() << "offset:" << offset; } +#endif /*! \class QContiguousCache \brief The QContiguousCache class is a template class that provides a contiguous cache. diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 5cd1582..2437f63 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -49,8 +49,10 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +#undef QT_QCONTIGUOUSCACHE_DEBUG QT_MODULE(Core) + struct Q_CORE_EXPORT QContiguousCacheData { QBasicAtomicInt ref; @@ -60,7 +62,9 @@ struct Q_CORE_EXPORT QContiguousCacheData int offset; uint sharable : 1; +#ifdef QT_QCONTIGUOUSCACHE_DEBUG void dump() const; +#endif }; template @@ -131,8 +135,10 @@ public: { return d->offset >= 0 && d->offset < INT_MAX - d->count && (d->offset % d->alloc) == d->start; } inline void normalizeIndexes() { d->offset = d->start; } - // debug + +#ifdef QT_QCONTIGUOUSCACHE_DEBUG void dump() const { p->dump(); } +#endif private: void detach_helper(); -- cgit v0.12 From 2248d63c1a32ae84bb6d0bde9021a8074db1b4c9 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Tue, 26 May 2009 10:46:54 +1000 Subject: Fixed qmake writing targets into the root of the current drive when DESTDIR=./ and using Windows, nmake and shadow builds. qmake would canonicalize the DESTDIR of "./" to "". Then it would check if the original DESTDIR ended with "/", and if so, append it to the new DESTDIR, resulting in a DESTDIR of "/" - the root of the current drive. Don't do that. This bug doesn't occur with in-source builds because qmake detects that the source and build directories are the same directory and replaces the DESTDIR of "./" with "" before it reaches the buggy code. Autotest: included Reviewed-by: Lincoln Ramsay --- qmake/generators/win32/winmakefile.cpp | 2 +- tests/auto/qmake/tst_qmake.cpp | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 87f55cf..c7f00dd 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -626,7 +626,7 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t) // do this here so we can set DEST_TARGET to be the complete path to the final target if it is needed. QString orgDestDir = var("DESTDIR"); QString destDir = Option::fixPathToTargetOS(orgDestDir, false); - if (orgDestDir.endsWith('/') || orgDestDir.endsWith(Option::dir_sep)) + if (!destDir.isEmpty() && (orgDestDir.endsWith('/') || orgDestDir.endsWith(Option::dir_sep))) destDir += Option::dir_sep; QString target = QString(project->first("TARGET")+project->first("TARGET_EXT")); target.remove("\""); diff --git a/tests/auto/qmake/tst_qmake.cpp b/tests/auto/qmake/tst_qmake.cpp index 70f1f3c..1178c81 100644 --- a/tests/auto/qmake/tst_qmake.cpp +++ b/tests/auto/qmake/tst_qmake.cpp @@ -63,6 +63,7 @@ public slots: private slots: void simple_app(); + void simple_app_shadowbuild(); void simple_lib(); void simple_dll(); void subdirs(); @@ -143,6 +144,21 @@ void tst_qmake::simple_app() QVERIFY( test_compiler.removeMakefile( workDir ) ); } +void tst_qmake::simple_app_shadowbuild() +{ + QString workDir = base_path + "/testdata/simple_app"; + QString buildDir = base_path + "/testdata/simple_app_build"; + + QVERIFY( test_compiler.qmake( workDir, "simple_app", buildDir )); + QVERIFY( test_compiler.make( buildDir )); + QVERIFY( test_compiler.exists( buildDir, "simple_app", Exe, "1.0.0" )); + QVERIFY( test_compiler.makeClean( buildDir )); + QVERIFY( test_compiler.exists( buildDir, "simple_app", Exe, "1.0.0" )); // Should still exist after a make clean + QVERIFY( test_compiler.makeDistClean( buildDir )); + QVERIFY( !test_compiler.exists( buildDir, "simple_app", Exe, "1.0.0" )); // Should not exist after a make distclean + QVERIFY( test_compiler.removeMakefile( buildDir ) ); +} + void tst_qmake::simple_dll() { QString workDir = base_path + "/testdata/simple_dll"; -- cgit v0.12 From 682b854872c26d7408d79131217825fb8ddace6a Mon Sep 17 00:00:00 2001 From: Michael Goddard Date: Tue, 26 May 2009 10:39:36 +1000 Subject: BT:Fix access of deleted memory with a static QCursor. If a QCursor with a predefined shape is declared static, it could be destroyed after the application dtor has already cleaned up QCursor memory. Task-number: 254467 Reviewed-by: Rhys Weatherley --- src/gui/kernel/qcursor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index ed7e020..598f4ba 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -375,7 +375,9 @@ void QCursorData::cleanup() return; for (int shape = 0; shape <= Qt::LastCursor; ++shape) { - delete qt_cursorTable[shape]; + // In case someone has a static QCursor defined with this shape + if (!qt_cursorTable[shape]->ref.deref()) + delete qt_cursorTable[shape]; qt_cursorTable[shape] = 0; } QCursorData::initialized = false; -- cgit v0.12 From 51167b0f2f7b3989ed448160fda3209e9382663a Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 26 May 2009 08:40:54 +0200 Subject: Fix build failure on MacOS 10.4 It seems GLint is typedefed to long on 10.4. Reviewed-By: Rhys Weatherley --- src/opengl/qglframebufferobject.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 8af9f63..2b7ad4f 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -288,7 +288,7 @@ public: ~QGLFramebufferObjectPrivate() {} void init(const QSize& sz, QGLFramebufferObject::Attachment attachment, - GLenum internal_format, GLenum texture_target, int samples = 0); + GLenum internal_format, GLenum texture_target, GLint samples = 0); bool checkFramebufferStatus() const; GLuint texture; GLuint fbo; @@ -350,7 +350,7 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const } void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::Attachment attachment, - GLenum texture_target, GLenum internal_format, int samples) + GLenum texture_target, GLenum internal_format, GLint samples) { ctx = const_cast(QGLContext::currentContext()); bool ext_detected = (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject); @@ -490,7 +490,7 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At QT_CHECK_GLERROR(); format.setTextureTarget(target); - format.setSamples(samples); + format.setSamples(int(samples)); format.setAttachment(fbo_attachment); format.setInternalFormat(internal_format); } -- cgit v0.12 From baec0ecd314c6e9563bd56cf19571ca71d7d11cd Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 26 May 2009 09:23:55 +0200 Subject: Fixed docs warnings for Animation API --- src/corelib/animation/qanimationgroup.cpp | 2 +- src/corelib/animation/qpropertyanimation.h | 4 ++-- src/corelib/animation/qvariantanimation.cpp | 15 ++++++++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp index ed06eff..839b522 100644 --- a/src/corelib/animation/qanimationgroup.cpp +++ b/src/corelib/animation/qanimationgroup.cpp @@ -236,7 +236,7 @@ void QAnimationGroup::removeAnimation(QAbstractAnimation *animation) \note The ownership of the animation is transferred to the caller. - \sa removeAnimation(), addAnimation(), insertAnimation(), indexOfAnimation() + \sa removeAnimation(), addAnimation(), insertAnimationAt(), indexOfAnimation() */ QAbstractAnimation *QAnimationGroup::takeAnimationAt(int index) { diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h index 5b06bd2..39317ba 100644 --- a/src/corelib/animation/qpropertyanimation.h +++ b/src/corelib/animation/qpropertyanimation.h @@ -72,11 +72,11 @@ public: protected: bool event(QEvent *event); - void updateCurrentValue(const QVariant &value); void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState); - Q_PRIVATE_SLOT(d_func(), void _q_targetDestroyed()); + private: + Q_PRIVATE_SLOT(d_func(), void _q_targetDestroyed()); Q_DISABLE_COPY(QPropertyAnimation) Q_DECLARE_PRIVATE(QPropertyAnimation) }; diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index a6834bb..4542a86 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -63,9 +63,8 @@ QT_BEGIN_NAMESPACE shared functionality. QVariantAnimation cannot be used directly as it is an abstract - class; it does not implement - \l{QAbstractAnimation::}{updateCurrentValue()} from - QAbstractAnimation. The class performs interpolation over + class; it has a pure virtual method called updateCurrentValue(). + The class performs interpolation over \l{QVariant}s, but leaves using the interpolated values to its subclasses. Currently, Qt provides QPropertyAnimation, which animates Qt \l{Qt's Property System}{properties}. See the @@ -130,6 +129,16 @@ QT_BEGIN_NAMESPACE \sa currentValue, startValue, endValue */ +/*! + \fn void QVariantAnimation::updateCurrentValue(const QVariant &value) = 0; + + This pure virtual function is called every time the animation's current + value changes. The \a value argument is the new current value. + + \sa currentValue +*/ + + static bool animationValueLessThan(const QVariantAnimation::KeyValue &p1, const QVariantAnimation::KeyValue &p2) { return p1.first < p2.first; -- cgit v0.12 From 02b49e3bf1556c76cd59d205529f04a390cfa433 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 26 May 2009 09:48:09 +0200 Subject: Fix doc warnings for Phonon --- doc/src/phonon-api.qdoc | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/doc/src/phonon-api.qdoc b/doc/src/phonon-api.qdoc index dd37fe2..5deb64e 100644 --- a/doc/src/phonon-api.qdoc +++ b/doc/src/phonon-api.qdoc @@ -1032,6 +1032,7 @@ \value Stream The MediaSource object describes a data stream. This is the type used for \l{QIODevice}s. Note that a stream opened with a QUrl, will still be of the Url type. + \value Empty The media source doesn't have a source. \sa MediaSource::type() */ @@ -2026,6 +2027,15 @@ */ /*! + \fn void Phonon::MediaObject::clear() + + Stops and removes all playing and enqueued media sources. + + \sa setCurrentSource() +*/ + + +/*! \fn void Phonon::MediaObject::stateChanged(Phonon::State newstate, Phonon::State oldstate) This signal is emitted when the state of the MediaObject has changed. @@ -3027,6 +3037,12 @@ */ /*! + \typedef Phonon::AudioOutputInterface + \inmodule Phonon + \internal +*/ + +/*! \class Phonon::AudioOutputInterface40 \inmodule Phonon \since 4.4 @@ -3251,7 +3267,19 @@ /*! \fn bool Phonon::Path::operator!=(const Path &p) const; - Returns true if this Path is not equal to \a p; otherwise returns false; + Returns true if this Path is not equal to \a p; otherwise returns false. +*/ + +/*! + \fn MediaNode *Phonon::Path::source() const; + + Returns the source MediaNode used by the path. +*/ + +/*! + \fn MediaNode *Phonon::Path::sink() const; + + Returns the sink MediaNode used by the path. */ /*! @@ -4878,7 +4906,7 @@ */ /*! - \typedef typedef void (*CleanUpFunction)() + \typedef Phonon::CleanUpFunction \inmodule Phonon \internal */ -- cgit v0.12 From 5839b16a73c36ff7636c13f841d26e6a5e0c5435 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 28 Apr 2009 17:37:52 +0200 Subject: fix double slash prepending causing troubles on WinCE Before adding a / to the path one should check if it doesn't end with one already. Otherwise one might get paths like //My Documents on WinCE causing the native call to crash the filesystem service on that system. Reviewed-by: alexis --- src/gui/dialogs/qfilesystemmodel_p.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/gui/dialogs/qfilesystemmodel_p.h b/src/gui/dialogs/qfilesystemmodel_p.h index 0a1265a..61e8b4c 100644 --- a/src/gui/dialogs/qfilesystemmodel_p.h +++ b/src/gui/dialogs/qfilesystemmodel_p.h @@ -164,9 +164,12 @@ public: QHash::const_iterator iterator; for(iterator = children.constBegin() ; iterator != children.constEnd() ; ++iterator) { //On windows the root (My computer) has no path so we don't want to add a / for nothing (e.g. /C:/) - if (!path.isEmpty()) - iterator.value()->updateIcon(iconProvider, path + QLatin1Char('/') + iterator.value()->fileName); - else + if (!path.isEmpty()) { + if (path.endsWith(QLatin1Char('/'))) + iterator.value()->updateIcon(iconProvider, path + iterator.value()->fileName); + else + iterator.value()->updateIcon(iconProvider, path + QLatin1Char('/') + iterator.value()->fileName); + } else iterator.value()->updateIcon(iconProvider, iterator.value()->fileName); } } @@ -177,9 +180,12 @@ public: QHash::const_iterator iterator; for(iterator = children.constBegin() ; iterator != children.constEnd() ; ++iterator) { //On windows the root (My computer) has no path so we don't want to add a / for nothing (e.g. /C:/) - if (!path.isEmpty()) - iterator.value()->retranslateStrings(iconProvider, path + QLatin1Char('/') + iterator.value()->fileName); - else + if (!path.isEmpty()) { + if (path.endsWith(QLatin1Char('/'))) + iterator.value()->retranslateStrings(iconProvider, path + iterator.value()->fileName); + else + iterator.value()->retranslateStrings(iconProvider, path + QLatin1Char('/') + iterator.value()->fileName); + } else iterator.value()->retranslateStrings(iconProvider, iterator.value()->fileName); } } -- cgit v0.12 From e7a607f0f1f7837a26bf95248504497b0534e357 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 26 May 2009 10:19:02 +0200 Subject: qdoc: Indicate that qAbs(T& v) compares v to a 0 of type T. Task-number: 246789 --- doc/src/index.qdoc | 1 + src/corelib/global/qglobal.cpp | 49 +++++++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index 4ead9e4..9846ac4 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -153,6 +153,7 @@
  • All Overviews and HOWTOs
  • Qt Widget Gallery
  • Class Chart
  • +
  • Qt Global Declarations
  • diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 8324d05..f767bb9 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -125,7 +125,8 @@ QT_BEGIN_NAMESPACE If you want to use QFlags for your own enum types, use the Q_DECLARE_FLAGS() and Q_DECLARE_OPERATORS_FOR_FLAGS(). - For example: + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 1 @@ -442,14 +443,18 @@ QT_BEGIN_NAMESPACE function. You can retrieve the minimum and maximum of two given objects using qMin() and qMax() respectively. All these functions return a corresponding template type; the template types can be - replaced by any other type. For example: + replaced by any other type. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 3 also contains functions that generate messages from the given string argument: qCritical(), qDebug(), qFatal() and qWarning(). These functions call the message handler with the - given message. For example: + given message. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 4 @@ -694,7 +699,9 @@ QT_BEGIN_NAMESPACE \relates Wraps the signed 64-bit integer \a literal in a - platform-independent way. For example: + platform-independent way. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 8 @@ -705,7 +712,9 @@ QT_BEGIN_NAMESPACE \relates Wraps the unsigned 64-bit integer \a literal in a - platform-independent way. For example: + platform-independent way. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 9 @@ -734,7 +743,11 @@ QT_BEGIN_NAMESPACE /*! \fn const T &qAbs(const T &value) \relates - Returns the absolute value of \a value. For example: + Compares \a value to the 0 of type T and returns the absolute + value. Thus if T is \e {double}, then \a value is compared to + \e{(double) 0}. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 10 */ @@ -742,7 +755,9 @@ QT_BEGIN_NAMESPACE /*! \fn int qRound(qreal value) \relates - Rounds \a value to the nearest integer. For example: + Rounds \a value to the nearest integer. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 11 */ @@ -750,7 +765,9 @@ QT_BEGIN_NAMESPACE /*! \fn qint64 qRound64(qreal value) \relates - Rounds \a value to the nearest 64-bit integer. For example: + Rounds \a value to the nearest 64-bit integer. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 12 */ @@ -758,7 +775,9 @@ QT_BEGIN_NAMESPACE /*! \fn const T &qMin(const T &value1, const T &value2) \relates - Returns the minimum of \a value1 and \a value2. For example: + Returns the minimum of \a value1 and \a value2. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 13 @@ -768,7 +787,9 @@ QT_BEGIN_NAMESPACE /*! \fn const T &qMax(const T &value1, const T &value2) \relates - Returns the maximum of \a value1 and \a value2. For example: + Returns the maximum of \a value1 and \a value2. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 14 @@ -779,7 +800,9 @@ QT_BEGIN_NAMESPACE \relates Returns \a value bounded by \a min and \a max. This is equivalent - to qMax(\a min, qMin(\a value, \a max)). For example: + to qMax(\a min, qMin(\a value, \a max)). + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 15 @@ -925,7 +948,9 @@ QT_BEGIN_NAMESPACE 4.1.2, the QT_VERSION macro will expand to 0x040102. You can use QT_VERSION to use the latest Qt features where - available. For example: + available. + + Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 16 -- cgit v0.12 From 2a390bb481a2433a239a9198e463c9337a26db59 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 25 May 2009 18:32:46 +0200 Subject: Fixed: QSortFilterProxyModel setDynamicSortFilter doesn't works when setting the model initially This was caused by two different bug: - In the QSortFilterProxyModel, we need to re-sort when setting the source model change the sorting column (happen when setting a model initially) - In the treeview, we need to activate the sorting even if there is no column yet (because the initial model is empty Task-number: 254234 Reviewed-by: Thierry BT: --- src/gui/itemviews/qheaderview.cpp | 4 ++- src/gui/itemviews/qsortfilterproxymodel.cpp | 3 ++- src/gui/itemviews/qtreeview.cpp | 8 +++--- .../tst_qsortfilterproxymodel.cpp | 10 ++++++++ tests/auto/qtreeview/tst_qtreeview.cpp | 29 +++++++++++++++++++++- 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index dc63b25..86ece40 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -1267,8 +1267,10 @@ void QHeaderView::setSortIndicator(int logicalIndex, Qt::SortOrder order) d->sortIndicatorSection = logicalIndex; d->sortIndicatorOrder = order; - if (logicalIndex >= d->sectionCount) + if (logicalIndex >= d->sectionCount) { + emit sortIndicatorChanged(logicalIndex, order); return; // nothing to do + } if (old != logicalIndex && ((logicalIndex >= 0 && resizeMode(logicalIndex) == ResizeToContents) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index 43feda8..92dfd19 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1518,7 +1518,8 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) d->clear_mapping(); reset(); - d->update_source_sort_column(); + if (d->update_source_sort_column() && d->dynamic_sortfilter) + d->sort(); } /*! diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 62c1277..1070648 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -246,7 +246,7 @@ void QTreeView::setModel(QAbstractItemModel *model) connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset())); if (d->sortingEnabled) - sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); + d->_q_sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); } /*! @@ -846,17 +846,19 @@ void QTreeView::setExpanded(const QModelIndex &index, bool expanded) void QTreeView::setSortingEnabled(bool enable) { Q_D(QTreeView); - d->sortingEnabled = enable; header()->setSortIndicatorShown(enable); header()->setClickable(enable); if (enable) { + //sortByColumn has to be called before we connect or set the sortingEnabled flag + // because otherwise it will not call sort on the model. + sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder))); - sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); } else { disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder))); } + d->sortingEnabled = enable; } bool QTreeView::isSortingEnabled() const diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index bd66fdf..80d90a6 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -2585,6 +2585,16 @@ void tst_QSortFilterProxyModel::task248868_dynamicSorting() QModelIndex index = proxy1.index(row, 0, QModelIndex()); QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row)); } + + //set up the sorting before seting the model up + QSortFilterProxyModel proxy2; + proxy2.setDynamicSortFilter(true); + proxy2.sort(0); + proxy2.setSourceModel(&model2); + for (int row = 0; row < proxy2.rowCount(QModelIndex()); ++row) { + QModelIndex index = proxy2.index(row, 0, QModelIndex()); + QCOMPARE(proxy2.data(index, Qt::DisplayRole).toString(), expected.at(row)); + } } class QtTestModel: public QAbstractItemModel diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index 655ea4e..54d6619 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -225,6 +225,7 @@ private slots: void task238873_avoidAutoReopening(); void task244304_clickOnDecoration(); void task246536_scrollbarsNotWorking(); + void task254234_proxySort(); }; class QtTestModel: public QAbstractItemModel @@ -2493,7 +2494,6 @@ void tst_QTreeView::sortByColumn() QCOMPARE(view.header()->sortIndicatorSection(), 0); QCOMPARE(view.model()->data(view.model()->index(0,0)).toString(), QString::fromLatin1("a")); QCOMPARE(view.model()->data(view.model()->index(1,0)).toString(), QString::fromLatin1("b")); - } /* @@ -3272,5 +3272,32 @@ void tst_QTreeView::task246536_scrollbarsNotWorking() QVERIFY(o.count > 0); } +void tst_QTreeView::task254234_proxySort() +{ + //based on tst_QTreeView::sortByColumn + // it used not to work when setting the source of a proxy after enabling sorting + QTreeView view; + QStandardItemModel model(4,2); + model.setItem(0,0,new QStandardItem("b")); + model.setItem(1,0,new QStandardItem("d")); + model.setItem(2,0,new QStandardItem("c")); + model.setItem(3,0,new QStandardItem("a")); + model.setItem(0,1,new QStandardItem("e")); + model.setItem(1,1,new QStandardItem("g")); + model.setItem(2,1,new QStandardItem("h")); + model.setItem(3,1,new QStandardItem("f")); + + view.sortByColumn(1); + view.setSortingEnabled(true); + + QSortFilterProxyModel proxy; + proxy.setDynamicSortFilter(true); + view.setModel(&proxy); + proxy.setSourceModel(&model); + QCOMPARE(view.header()->sortIndicatorSection(), 1); + QCOMPARE(view.model()->data(view.model()->index(0,1)).toString(), QString::fromLatin1("h")); + QCOMPARE(view.model()->data(view.model()->index(1,1)).toString(), QString::fromLatin1("g")); +} + QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" -- cgit v0.12 From e33415a700a7d1de706633970ed69936e3b2145e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 26 May 2009 10:18:46 +0200 Subject: Fix the previous fix. The previous fix fails on msvc-2005, since QString::setNum() does not handle rounding of numbers such as 0.015625 consistently. --- tests/auto/qeasingcurve/tst_qeasingcurve.cpp | 182 +-------------------------- 1 file changed, 5 insertions(+), 177 deletions(-) diff --git a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp index 8fe15b1..b25cdc7 100644 --- a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp @@ -371,182 +371,6 @@ void tst_QEasingCurve::valueForProgress_data() << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) << (RealList() << 0.5 << 0.7939 << 0.9755 << 0.9755 << 0.7939 << 0.5 << 0.2061 << 0.02447 << 0.02447 << 0.2061 << 0.5); - /* - QTest::newRow("InQuad") << int(QEasingCurve::InQuad) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (RealList() << 0 << 0.01 << 0.04 << 0.09 << 0.16 << 0.25 << 0.36 << 0.49 << 0.64 << 0.81 << 1); - QTest::newRow("OutQuad") << int(QEasingCurve::OutQuad) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0.19 << 0.36 << 0.51 << 0.64 << 0.75 << 0.84 << 0.91 << 0.96 << 0.99 << 1); - - QTest::newRow("InOutQuad") << int(QEasingCurve::InOutQuad) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 2 << 8 << 18 << 32 << 50 << 68 << 82 << 92 << 98 << 100); - - QTest::newRow("OutInQuad") << int(QEasingCurve::OutInQuad) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 18 << 32 << 42 << 48 << 50 << 52 << 57 << 68 << 82 << 100); - - QTest::newRow("InCubic") << int(QEasingCurve::InCubic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 2 << 6 << 12 << 21 << 34 << 51 << 72 << 100); - - QTest::newRow("OutCubic") << int(QEasingCurve::OutCubic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 27 << 48 << 65 << 78 << 87 << 93 << 97 << 99 << 99 << 100); - - QTest::newRow("InOutCubic") << int(QEasingCurve::InOutCubic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 3 << 10 << 25 << 50 << 74 << 89 << 96 << 99 << 100); - - QTest::newRow("OutInCubic") << int(QEasingCurve::OutInCubic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 24 << 39 << 46 << 49 << 50 << 50 << 53 << 60 << 75 << 100); - - QTest::newRow("InQuart") << int(QEasingCurve::InQuart) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 0 << 2 << 6 << 12 << 24 << 40 << 65 << 100); - - QTest::newRow("OutQuart") << int(QEasingCurve::OutQuart) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 34 << 59 << 75 << 87 << 93 << 97 << 99 << 99 << 99 << 100); - - QTest::newRow("InOutQuart") << int(QEasingCurve::InOutQuart) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 1 << 6 << 20 << 50 << 79 << 93 << 98 << 99 << 100); - - QTest::newRow("OutInQuart") << int(QEasingCurve::OutInQuart) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 29 << 43 << 48 << 49 << 50 << 50 << 51 << 56 << 70 << 100); - - QTest::newRow("InQuint") << int(QEasingCurve::InQuint) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 0 << 1 << 3 << 7 << 16 << 32 << 59 << 100); - - QTest::newRow("OutQuint") << int(QEasingCurve::OutQuint) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 40 << 67 << 83 << 92 << 96 << 98 << 99 << 99 << 99 << 100); - - QTest::newRow("InOutQuint") << int(QEasingCurve::InOutQuint) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 3 << 16 << 50 << 83 << 96 << 99 << 99 << 100); - - QTest::newRow("OutInQuint") << int(QEasingCurve::OutInQuint) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 33 << 46 << 49 << 49 << 50 << 50 << 50 << 53 << 66 << 100); - - QTest::newRow("InSine") << int(QEasingCurve::InSine) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 1 << 4 << 10 << 19 << 29 << 41 << 54 << 69 << 84 << 100); - - QTest::newRow("OutSine") << int(QEasingCurve::OutSine) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 15 << 30 << 45 << 58 << 70 << 80 << 89 << 95 << 98 << 100); - - QTest::newRow("InOutSine") << int(QEasingCurve::InOutSine) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 2 << 9 << 20 << 34 << 49 << 65 << 79 << 90 << 97 << 100); - - QTest::newRow("OutInSine") << int(QEasingCurve::OutInSine) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 15 << 29 << 40 << 47 << 50 << 52 << 59 << 70 << 84 << 100); - - QTest::newRow("InExpo") << int(QEasingCurve::InExpo) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 0 << 1 << 3 << 6 << 12 << 24 << 49 << 100); - - QTest::newRow("OutExpo") << int(QEasingCurve::OutExpo) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 50 << 75 << 87 << 93 << 96 << 98 << 99 << 99 << 99 << 100); - - QTest::newRow("InOutExpo") << int(QEasingCurve::InOutExpo) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 3 << 12 << 50 << 87 << 96 << 99 << 99 << 100); - - QTest::newRow("OutInExpo") << int(QEasingCurve::OutInExpo) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 37 << 46 << 49 << 49 << 50 << 50 << 50 << 53 << 62 << 100); - - QTest::newRow("InCirc") << int(QEasingCurve::InCirc) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 2 << 4 << 8 << 13 << 19 << 28 << 40 << 56 << 100); - - QTest::newRow("OutCirc") << int(QEasingCurve::OutCirc) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 43 << 59 << 71 << 80 << 86 << 91 << 95 << 97 << 99 << 100); - - QTest::newRow("InOutCirc") << int(QEasingCurve::InOutCirc) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 1 << 4 << 9 << 20 << 50 << 80 << 89 << 95 << 98 << 100); - - QTest::newRow("OutInCirc") << int(QEasingCurve::OutInCirc) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 29 << 40 << 45 << 48 << 50 << 51 << 54 << 60 << 70 << 100); - - QTest::newRow("InElastic") << int(QEasingCurve::InElastic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << 0 << 1 << -1 << -3 << 12 << -12 << -25 << 100); - - QTest::newRow("OutElastic") << int(QEasingCurve::OutElastic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 125 << 112 << 87 << 103 << 101 << 98 << 100 << 100 << 99 << 100); - - QTest::newRow("InOutElastic") << int(QEasingCurve::InOutElastic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 0 << 0 << -1 << -6 << 50 << 106 << 101 << 99 << 100 << 100); - - QTest::newRow("OutInElastic") << int(QEasingCurve::OutInElastic) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 37 << 56 << 49 << 49 << 50 << 49 << 50 << 53 << 24 << 100); - - QTest::newRow("InBack") << int(QEasingCurve::InBack) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << -1 << -4 << -8 << -9 << -8 << -2 << 9 << 29 << 59 << 100); - - QTest::newRow("OutBack") << int(QEasingCurve::OutBack) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 40 << 70 << 90 << 102 << 108 << 109 << 108 << 104 << 101 << 100); - - QTest::newRow("InOutBack") << int(QEasingCurve::InOutBack) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << -3 << -9 << -7 << 8 << 50 << 91 << 107 << 109 << 103 << 100); - - QTest::newRow("OutInBack") << int(QEasingCurve::OutInBack) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 35 << 51 << 54 << 52 << 50 << 47 << 45 << 48 << 64 << 100); - - QTest::newRow("InBounce") << int(QEasingCurve::InBounce) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 1 << 6 << 6 << 22 << 23 << 9 << 31 << 69 << 92 << 100); - - QTest::newRow("OutBounce") << int(QEasingCurve::OutBounce) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 7 << 30 << 68 << 90 << 76 << 77 << 93 << 94 << 98 << 100); - - QTest::newRow("InOutBounce") << int(QEasingCurve::InOutBounce) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 3 << 11 << 4 << 34 << 50 << 65 << 95 << 88 << 97 << 100); - - QTest::newRow("OutInBounce") << int(QEasingCurve::OutInBounce) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 15 << 40 << 27 << 43 << 50 << 56 << 72 << 58 << 84 << 100); - - QTest::newRow("InCurve") << int(QEasingCurve::InCurve) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 2 << 10 << 23 << 37 << 50 << 60 << 70 << 80 << 90 << 100); - - QTest::newRow("OutCurve") << int(QEasingCurve::OutCurve) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 10 << 20 << 30 << 39 << 50 << 62 << 76 << 89 << 97 << 100); - - QTest::newRow("SineCurve") << int(QEasingCurve::SineCurve) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 0 << 9 << 34 << 65 << 90 << 100 << 90 << 65 << 34 << 9 << 0); - - QTest::newRow("CosineCurve") << int(QEasingCurve::CosineCurve) - << (IntList() << 0 << 10 << 20 << 30 << 40 << 50 << 60 << 70 << 80 << 90 << 100) - << (IntList() << 50 << 79 << 97 << 97 << 79 << 50 << 20 << 2 << 2 << 20 << 49); -*/ } @@ -590,7 +414,11 @@ void tst_QEasingCurve::valueForProgress() // converting ease to 4 precision qreal to match the generated samples qreal easeConv = qreal(QString().setNum(ease, 'g', 4).toDouble()); qreal ex = expected.at(i); - QVERIFY(qFuzzyCompare(easeConv, ex)); + + // the least significant digit it is still subject to rounding errors + qreal error = easeConv - ex; + // accept the potential rounding error in the least significant digit + QVERIFY(error <= 0.00001 ); } #endif } -- cgit v0.12 From 86598234d8c055fe8dbc474d292619d453cc9f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Tue, 26 May 2009 11:03:24 +0200 Subject: BT: Google suggest example not launching from the Qt Demo app. The example was installed in the wrong directory. Task-number: 254452 Reviewed-by: Kim --- examples/network/googlesuggest/googlesuggest.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/network/googlesuggest/googlesuggest.pro b/examples/network/googlesuggest/googlesuggest.pro index afd600f..33b79de 100644 --- a/examples/network/googlesuggest/googlesuggest.pro +++ b/examples/network/googlesuggest/googlesuggest.pro @@ -3,7 +3,7 @@ SOURCES = main.cpp searchbox.cpp googlesuggest.cpp HEADERS = searchbox.h googlesuggest.h # install -target.path = $$[QT_INSTALL_EXAMPLES]/webkit/googlesuggest +target.path = $$[QT_INSTALL_EXAMPLES]/network/googlesuggest sources.files = $$SOURCES $$HEADERS *.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/webkit/googlesuggest +sources.path = $$[QT_INSTALL_EXAMPLES]/network/googlesuggest INSTALLS += target sources -- cgit v0.12 From 7733f81af953a1ddaa7debc12bb29b101c5bc101 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 26 May 2009 10:40:26 +0200 Subject: Fixed keywords signals and slots to Q_SIGNALS and Q_SLOTS --- src/corelib/io/qfilesystemwatcher.cpp | 2 +- src/corelib/io/qnoncontiguousbytedevice_p.h | 2 +- src/corelib/io/qtextstream.cpp | 2 +- src/corelib/kernel/qtimer.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index e073a08..65cfb71 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -118,7 +118,7 @@ public: void stop(); -private slots: +private Q_SLOTS: void timeout(); }; diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h index 2a7e40b..acfc6eb 100644 --- a/src/corelib/io/qnoncontiguousbytedevice_p.h +++ b/src/corelib/io/qnoncontiguousbytedevice_p.h @@ -77,7 +77,7 @@ protected: virtual ~QNonContiguousByteDevice(); bool resetDisabled; -signals: +Q_SIGNALS: void readyRead(); void readProgress(qint64 current, qint64 total); }; diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 4563e84..7c925f1 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -333,7 +333,7 @@ public: this->stream = stream; } -public slots: +public Q_SLOTS: inline void flushStream() { stream->flush(); } private: diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 4b3feb0..08821d4 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -269,7 +269,7 @@ class QSingleShotTimer : public QObject public: ~QSingleShotTimer(); QSingleShotTimer(int msec, QObject *r, const char * m); -signals: +Q_SIGNALS: void timeout(); protected: void timerEvent(QTimerEvent *); -- cgit v0.12 From 5345306c9a0a3b10dbf640253b8b2287c762b081 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 26 May 2009 11:36:16 +0200 Subject: Fixed a bug in animation when you set a start value that doesn't have the same type as the property For example, if you set a start value of 0 (integer) for a qreal animation, it would not work. Reviewed-by: janarve --- src/corelib/animation/qvariantanimation.cpp | 10 ++- .../qpropertyanimation/tst_qpropertyanimation.cpp | 77 ++++++++++++++++------ 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 4542a86..239add9 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -179,10 +179,14 @@ void QVariantAnimationPrivate::convertValues(int t) //this ensures that all the keyValues are of type t for (int i = 0; i < keyValues.count(); ++i) { QVariantAnimation::KeyValue &pair = keyValues[i]; - if (pair.second.userType() != t) - pair.second.convert(static_cast(t)); + pair.second.convert(static_cast(t)); } - interpolator = 0; // if the type changed we need to update the interpolator + //we also need update to the current interval if needed + currentInterval.start.second.convert(static_cast(t)); + currentInterval.end.second.convert(static_cast(t)); + + //... and the interpolator + interpolator = 0; } /*! diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index 7e910d4..0aeac91 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -63,6 +63,18 @@ protected: } }; +class MyObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal x READ x WRITE setX) +public: + MyObject() : m_x(0) { } + qreal x() const { return m_x; } + void setX(qreal x) { m_x = x; } +private: + qreal m_x; +}; + class tst_QPropertyAnimation : public QObject { Q_OBJECT @@ -92,6 +104,7 @@ private slots: void startWithoutStartValue(); void playForwardBackward(); void interpolated(); + void setStartEndValues_data(); void setStartEndValues(); void zeroDurationStart(); void operationsInStates_data(); @@ -283,7 +296,7 @@ void tst_QPropertyAnimation::statesAndSignals() void tst_QPropertyAnimation::deletion1() { QObject *object = new QWidget; - QPointer anim = new QPropertyAnimation(object,"minimumWidth"); + QPointer anim = new QPropertyAnimation(object, "minimumWidth"); //test that the animation is deleted correctly depending of the deletion flag passed in start() QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); @@ -686,52 +699,78 @@ void tst_QPropertyAnimation::interpolated() } } +Q_DECLARE_METATYPE(QVariant) + +void tst_QPropertyAnimation::setStartEndValues_data() +{ + QTest::addColumn("propertyName"); + QTest::addColumn("initialValue"); + QTest::addColumn("startValue"); + QTest::addColumn("endValue"); + + QTest::newRow("dynamic property") << QByteArray("ole") << QVariant(42) << QVariant(0) << QVariant(10); + QTest::newRow("real property, with unmatching types") << QByteArray("x") << QVariant(42.) << QVariant(0) << QVariant(10.); +} + void tst_QPropertyAnimation::setStartEndValues() { + MyObject object; + QFETCH(QByteArray, propertyName); + QFETCH(QVariant, initialValue); + QFETCH(QVariant, startValue); + QFETCH(QVariant, endValue); + //this tests the start value, end value and default start value - QObject o; - o.setProperty("ole", 42); - QPropertyAnimation anim(&o, "ole"); + object.setProperty(propertyName, initialValue); + QPropertyAnimation anim(&object, propertyName); QVariantAnimation::KeyValues values; QCOMPARE(anim.keyValues(), values); //let's add a start value - anim.setStartValue(0); - values << QVariantAnimation::KeyValue(0, 0); + anim.setStartValue(startValue); + values << QVariantAnimation::KeyValue(0, startValue); QCOMPARE(anim.keyValues(), values); - anim.setEndValue(10); - values << QVariantAnimation::KeyValue(1, 10); + anim.setEndValue(endValue); + values << QVariantAnimation::KeyValue(1, endValue); QCOMPARE(anim.keyValues(), values); //now we can play with objects - QCOMPARE(o.property("ole").toInt(), 42); - QCOMPARE(o.property("ole").toInt(), 42); + QCOMPARE(object.property(propertyName).toDouble(), initialValue.toDouble()); anim.start(); QVERIFY(anim.startValue().isValid()); - QCOMPARE(o.property("ole"), anim.startValue()); + QCOMPARE(object.property(propertyName), anim.startValue()); + anim.setCurrentTime(anim.duration()/2); + QCOMPARE(object.property(propertyName).toDouble(), (startValue.toDouble() + endValue.toDouble())/2 ); //just in the middle of the animation + anim.setCurrentTime(anim.duration()); //we go to the end of the animation + QCOMPARE(anim.state(), QAnimationGroup::Stopped); //it should have stopped + QVERIFY(anim.endValue().isValid()); + QCOMPARE(object.property(propertyName), anim.endValue()); //end of the animations //now we remove the explicit start value and test the implicit one anim.stop(); - o.setProperty("ole", 42); + object.setProperty(propertyName, initialValue); + + //let's reset the start value values.remove(0); - anim.setStartValue(QVariant()); //reset the start value + anim.setStartValue(QVariant()); QCOMPARE(anim.keyValues(), values); QVERIFY(!anim.startValue().isValid()); + anim.start(); - QCOMPARE(o.property("ole").toInt(), 42); + QCOMPARE(object.property(propertyName), initialValue); anim.setCurrentTime(anim.duration()/2); - QCOMPARE(o.property("ole").toInt(), 26); //just in the middle of the animation - anim.setCurrentTime(anim.duration()); + QCOMPARE(object.property(propertyName).toDouble(), (initialValue.toDouble() + endValue.toDouble())/2 ); //just in the middle of the animation + anim.setCurrentTime(anim.duration()); //we go to the end of the animation QCOMPARE(anim.state(), QAnimationGroup::Stopped); //it should have stopped QVERIFY(anim.endValue().isValid()); - QCOMPARE(o.property("ole"), anim.endValue()); //end of the animations + QCOMPARE(object.property(propertyName), anim.endValue()); //end of the animations //now we set back the startValue - anim.setStartValue(5); + anim.setStartValue(startValue); QVERIFY(anim.startValue().isValid()); anim.start(); - QCOMPARE(o.property("ole").toInt(), 5); + QCOMPARE(object.property(propertyName), startValue); } void tst_QPropertyAnimation::zeroDurationStart() -- cgit v0.12 From 72ecfb3eb9b65ed2617942510fa0c9af5075f209 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Tue, 26 May 2009 12:03:13 +0200 Subject: Doc - more screenshots and adding better description Details: Work in progress --- doc/src/designer-manual.qdoc | 28 ++++++++++++++------------- doc/src/images/designer-choosing-form.png | Bin 38078 -> 39080 bytes doc/src/images/rgbController-arrangement.png | Bin 0 -> 10813 bytes 3 files changed, 15 insertions(+), 13 deletions(-) create mode 100644 doc/src/images/rgbController-arrangement.png diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index 03b74e6..77b208b 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -235,6 +235,7 @@ \page designer-to-know.html \contentspage {Qt Designer Manual}{Contents} + \title Getting to Know Qt Designer \tableofcontents @@ -408,6 +409,7 @@ \page designer-quick-start.html \contentspage {Qt Designer Manual}{Contents} + \title A Quick Start to Qt Designer Using \QD involves \bold four basic steps: @@ -419,16 +421,14 @@ \o Preview the form \endlist - \omit \image rgbController-screenshot.png - \endomit - Suppose you would like to design a small widget (see screenshot above) - that contains the controls needed to manipulate Red, Green and Blue (RGB) - values -- a type of widget that can be seen everywhere in image - manipulation programs. + Suppose you would like to design a small widget (see screenshot above) that + contains the controls needed to manipulate Red, Green and Blue (RGB) values + -- a type of widget that can be seen everywhere in image manipulation + programs. - \table + \table \row \i \inlineimage designer-choosing-form.png \i \bold{Choosing a Form} @@ -436,20 +436,22 @@ You start by choosing \gui Widget from the \gui{New Form} dialog. \endtable - Then you drag three labels, three spin boxes and three vertical sliders - on to your form. You can roughly arrange them according to how you would - like them to be laid out. + Then you drag three labels, three spin boxes and three vertical sliders on + to your form. To change the label's default text, simply double-click on + it. The screenshot below shows the form after all three labels have been + renamed. + + You can roughly arrange them according to how you would like them to be + laid out. - \omit \table \row \o \inlineimage rgbController-widgetBox.png \o \inlineimage rgbController-arrangement.png \endtable - \endomit To ensure that they are laid out exactly like this in your program, you need to place these widgets into a layout. We will do this in groups of - three. Select the "RED" label. Then, hold down \key Shift while you select + three. Select the "RED" label. Then, hold down \key Ctrl while you select its corresponding spin box and slider. In the \gui{Form} menu, select \gui{Lay Out in a Grid}. diff --git a/doc/src/images/designer-choosing-form.png b/doc/src/images/designer-choosing-form.png index fa6e470..bee4b29 100644 Binary files a/doc/src/images/designer-choosing-form.png and b/doc/src/images/designer-choosing-form.png differ diff --git a/doc/src/images/rgbController-arrangement.png b/doc/src/images/rgbController-arrangement.png new file mode 100644 index 0000000..d9e8bab Binary files /dev/null and b/doc/src/images/rgbController-arrangement.png differ -- cgit v0.12 From 57df8bc3ddd2bc5aaf5c25cf3e311fe56ad50ffb Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 26 May 2009 12:07:01 +0200 Subject: qdoc: Indicate what iterator_categor means for container classes. Task-number: 245501 --- doc/src/qset.qdoc | 9 +++++---- src/corelib/tools/qlistdata.cpp | 6 ++++-- src/corelib/tools/qmap.cpp | 6 ++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/doc/src/qset.qdoc b/doc/src/qset.qdoc index afbedc3..6326219 100644 --- a/doc/src/qset.qdoc +++ b/doc/src/qset.qdoc @@ -685,11 +685,12 @@ */ /*! - \typedef QSet::iterator::iterator_category - \typedef QSet::const_iterator::iterator_category + \typedef QSet::iterator::iterator_category + \typedef QSet::const_iterator::iterator_category - \internal -*/ + Synonyms for \e {std::bidirectional_iterator_tag} indicating + these iterators are bidirectional iterators. + */ /*! \typedef QSet::iterator::difference_type diff --git a/src/corelib/tools/qlistdata.cpp b/src/corelib/tools/qlistdata.cpp index d40b6b6..34a5d80 100644 --- a/src/corelib/tools/qlistdata.cpp +++ b/src/corelib/tools/qlistdata.cpp @@ -1173,7 +1173,8 @@ void **QListData::erase(void **xi) /*! \typedef QList::iterator::iterator_category - \internal + A synonym for \e {std::random_access_iterator_tag} indicating + this iterator is a random access iterator. */ /*! \typedef QList::iterator::difference_type @@ -1432,7 +1433,8 @@ void **QListData::erase(void **xi) /*! \typedef QList::const_iterator::iterator_category - \internal + A synonym for \e {std::random_access_iterator_tag} indicating + this iterator is a random access iterator. */ /*! \typedef QList::const_iterator::difference_type diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index 0699400..07df28d 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -902,7 +902,8 @@ void QMapData::dump() /*! \typedef QMap::iterator::iterator_category - \internal + A synonym for \e {std::bidirectional_iterator_tag} indicating + this iterator is a bidirectional iterator. */ /*! \typedef QMap::iterator::pointer @@ -1123,7 +1124,8 @@ void QMapData::dump() /*! \typedef QMap::const_iterator::iterator_category - \internal + A synonym for \e {std::bidirectional_iterator_tag} indicating + this iterator is a bidirectional iterator. */ /*! \typedef QMap::const_iterator::pointer -- cgit v0.12 From 337ffb38e35ca43e4119ac0634499b226137692e Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 26 May 2009 12:08:45 +0200 Subject: Doc: Removed irrelevant links from the Qt for Windows CE documentation. Reviewed-by: Maurice Kalinowski --- doc/src/topics.qdoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/src/topics.qdoc b/doc/src/topics.qdoc index 301f0d4..6ef3a89 100644 --- a/doc/src/topics.qdoc +++ b/doc/src/topics.qdoc @@ -286,11 +286,9 @@ including ARM, Intel x86, MIPS and SH-4. \o \l {Qt for Windows CE Requirements} \o \l {Installing Qt on Windows CE} \o \l {Windows CE - Introduction to using Qt}{Introduction to using Qt} - \o \l {Qt Examples#Qt for Embedded Linux}{Examples} \endlist \o \list - \o \l {Qt for Embedded Linux Classes}{Classes} \o \l {Windows CE - Using shadow builds}{Using shadow builds} \o \l {Windows CE - Working with Custom SDKs}{Working with Custom SDKs} \endlist -- cgit v0.12 From 3037e466ebf21aa4a47a722a1e2ff497690cbef5 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 26 May 2009 12:31:23 +0200 Subject: Fix a crash in Phonon::EffectWidget When creating a UI based on double types we only assigned the control pointer in certain cases. This would crash because the tooltip did not check for the pointer, but the real issue was that we didnt assign the control in the first place. Task-number: 249710 Reviewed-by: Richard Moe Gustavsen --- src/3rdparty/phonon/phonon/effectwidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/phonon/effectwidget.cpp b/src/3rdparty/phonon/phonon/effectwidget.cpp index da5a51a..d5c6c81 100644 --- a/src/3rdparty/phonon/phonon/effectwidget.cpp +++ b/src/3rdparty/phonon/phonon/effectwidget.cpp @@ -165,6 +165,7 @@ void EffectWidgetPrivate::autogenerateUi() if (minValue == -1. && maxValue == 1.) { //Special case values between -1 and 1.0 to use a slider for improved usability QSlider *slider = new QSlider(Qt::Horizontal, q); + control = slider; slider->setRange(-SLIDER_RANGE, +SLIDER_RANGE); slider->setValue(int(SLIDER_RANGE * value.toDouble())); slider->setTickPosition(QSlider::TicksBelow); @@ -188,10 +189,10 @@ void EffectWidgetPrivate::autogenerateUi() break; } + if (control) { #ifndef QT_NO_TOOLTIP control->setToolTip(para.description()); #endif - if (control) { #ifndef QT_NO_SHORTCUT label->setBuddy(control); #endif -- cgit v0.12 From c666b88abcb2c5c120054ac3b0d304cd8225ded7 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 26 May 2009 12:34:03 +0200 Subject: Windows CE compile fix QFileInfo doesn't have a constructor for QLatin1Char and implicit conversion didn't work. Reviewed-by: Thierry --- src/corelib/io/qfsfileengine_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index aee9fde..82cde8b 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1298,7 +1298,7 @@ QFileInfoList QFSFileEngine::drives() } return ret; #else - ret.append(QLatin1Char('/')); + ret.append(QFileInfo(QLatin1Char('/'))); return ret; #endif } -- cgit v0.12 From 54f92419b23b425e32ad573db17f608a67936df1 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Tue, 26 May 2009 12:40:02 +0200 Subject: Clearifying QWebFrame docs Adding docs to toHtml() and toPlainText() Task-number: 253088 Rev-by: Ariya Hidayat Rev-by: David Boddie --- src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp index 5dc6363..e565476 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp @@ -268,7 +268,7 @@ void QWebFrame::addToJavaScriptWindowObject(const QString &name, QObject *object } /*! - Returns the frame's content, converted to HTML. + Returns the frame's content as HTML, enclosed in HTML and BODY tags. \sa setHtml(), toPlainText() */ @@ -280,7 +280,8 @@ QString QWebFrame::toHtml() const } /*! - Returns the content of this frame converted to plain text. + Returns the content of this frame converted to plain text, completely + stripped of all HTML formatting. \sa toHtml() */ -- cgit v0.12 From f640eca34f63631f938817b1254d0caf92cc9143 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 26 May 2009 10:04:53 +0200 Subject: Carbon, QFontDialog::getFont() ignore the "initial" parameter Seems like no code was written to handle other font engines than CoreText. Unfortunatly the engine on Carbon is ATSUI. This patch adds general code for converting a QFont to an NSFont so the dialog can support other engines than CoreText Task-number: 251957 Reviewed-by: Trenton Schulz --- src/gui/dialogs/qfontdialog_mac.mm | 39 ++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 13f7149..3be53db 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #import @@ -123,16 +124,16 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) QFont newFont; if (cocoaFont) { int pSize = qRound([cocoaFont pointSize]); - QString family(QCFString::toQString(reinterpret_cast([cocoaFont familyName]))); - QString typeface(QCFString::toQString(reinterpret_cast([cocoaFont fontName]))); -// qDebug() << "original family" << family << "typeface" << typeface << "psize" << pSize; + QString family(qt_mac_NSStringToQString([cocoaFont familyName])); + QString typeface(qt_mac_NSStringToQString([cocoaFont fontName])); + int hyphenPos = typeface.indexOf(QLatin1Char('-')); if (hyphenPos != -1) { typeface.remove(0, hyphenPos + 1); } else { typeface = QLatin1String("Normal"); } -// qDebug() << " massaged family" << family << "typeface" << typeface << "psize" << pSize; + newFont = QFontDatabase().font(family, typeface, pSize); newFont.setUnderline(resolveFont.underline()); newFont.setStrikeOut(resolveFont.strikeOut()); @@ -598,15 +599,37 @@ QFont QFontDialogPrivate::execCocoaFontPanel(bool *ok, const QFont &initial, } } -void QFontDialogPrivate::setFont(void * delegate, const QFont &font) +void QFontDialogPrivate::setFont(void *delegate, const QFont &font) { + QMacCocoaAutoReleasePool pool; QFontEngine *fe = font.d->engineForScript(QUnicodeTables::Common); + NSFontManager *mgr = [NSFontManager sharedFontManager]; + NSFont *nsFont = 0; + #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (qstrcmp(fe->name(), "CoreText") == 0) { - const NSFont *nsFont = reinterpret_cast(static_cast(fe)->ctfont); - [[NSFontManager sharedFontManager] setSelectedFont:nsFont isMultiple:NO]; - } + nsFont = reinterpret_cast(static_cast(fe)->ctfont); + } else #endif + { + int weight = 5; + NSFontTraitMask mask = 0; + if (font.style() == QFont::StyleItalic) { + mask |= NSItalicFontMask; + } + if (font.weight() == QFont::Bold) { + weight = 9; + mask |= NSBoldFontMask; + } + + NSFontManager *mgr = [NSFontManager sharedFontManager]; + nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(font.family()) + traits:mask + weight:weight + size:font.pointSize()]; + } + + [mgr setSelectedFont:nsFont isMultiple:NO]; [static_cast(delegate) setQtFont:font]; } -- cgit v0.12 From f552dc200d857505df500b3ce0b99d5f7c74c951 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 26 May 2009 13:26:14 +0200 Subject: We first remove the pixmap from the cache and then release the key If we don't remove the pixmap from QCache first then the key is invalid and the removal failed Reviewed-by: sroedal --- src/gui/image/qpixmapcache.cpp | 4 +++- tests/auto/qpixmapcache/tst_qpixmapcache.cpp | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 3cfc191..82b42b4 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -342,8 +342,10 @@ bool QPMCache::remove(const QString &key) bool QPMCache::remove(const QPixmapCache::Key &key) { + bool result = QCache::remove(key); + //We release the key after we removed it from the cache releaseKey(key); - return QCache::remove(key); + return result; } void QPMCache::resizeKeyArray(int size) diff --git a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp index 405ac34..fb5998a 100644 --- a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp @@ -369,6 +369,14 @@ void tst_QPixmapCache::remove() key = QPixmapCache::insert(p1); QCOMPARE(getPrivate(key)->key, 1); + //Test if pixmaps are correctly deleted + QPixmapCache::clear(); + key = QPixmapCache::insert(p1); + QCOMPARE(getPrivate(key)->key, 1); + QVERIFY(QPixmapCache::find(key, &p1) != 0); + QPixmapCache::remove(key); + QCOMPARE(p1.isDetached(), true); + //We mix both part of the API QPixmapCache::clear(); p1.fill(Qt::red); -- cgit v0.12 From c37c8370e4897d2e6191df2d1ccde43830ffb8d0 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Tue, 26 May 2009 13:42:33 +0200 Subject: Doc - more screenshots and better description --- doc/src/designer-manual.qdoc | 35 ++++++++--------------- doc/src/images/rgbController-final-layout.png | Bin 0 -> 11275 bytes doc/src/images/rgbController-form-gridLayout.png | Bin 0 -> 11235 bytes doc/src/images/rgbController-selectForLayout.png | Bin 0 -> 20981 bytes 4 files changed, 12 insertions(+), 23 deletions(-) create mode 100644 doc/src/images/rgbController-final-layout.png create mode 100644 doc/src/images/rgbController-form-gridLayout.png create mode 100644 doc/src/images/rgbController-selectForLayout.png diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index 77b208b..452782f 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -436,41 +436,32 @@ You start by choosing \gui Widget from the \gui{New Form} dialog. \endtable - Then you drag three labels, three spin boxes and three vertical sliders on - to your form. To change the label's default text, simply double-click on - it. The screenshot below shows the form after all three labels have been - renamed. - - You can roughly arrange them according to how you would like them to be - laid out. \table - \row \o \inlineimage rgbController-widgetBox.png - \o \inlineimage rgbController-arrangement.png - \endtable + \row + \i \inlineimage rgbController-arrangement.png + \i \bold{Placing Widgets on a Form} + Drag three labels, three spin boxes and three vertical sliders on to your + form. To change the label's default text, simply double-click on it. You + can arrange them according to how you would like them to be laid out. + \endtable + To ensure that they are laid out exactly like this in your program, you need to place these widgets into a layout. We will do this in groups of three. Select the "RED" label. Then, hold down \key Ctrl while you select its corresponding spin box and slider. In the \gui{Form} menu, select \gui{Lay Out in a Grid}. - \omit \table \row \i \inlineimage rgbController-form-gridLayout.png \i \inlineimage rgbController-selectForLayout.png \endtable - \endomit Repeat the step for the other two labels along with their corresponding - spin boxes and sliders as well. Your form will now look similar to the - screenshot below. - - \omit - \image rgbController-almostLaidOut.png - \endomit + spin boxes and sliders as well. The next step is to combine all three layouts into one \bold{main layout}. It is important that your form has a main layout; otherwise, the widgets @@ -478,7 +469,9 @@ layout, \gui{Right click} anywhere on your form, outside of the three separate layouts, and select \gui{Lay Out Horizontally}. Alternatively, you could also select \gui{Lay Out in a Grid} -- you will still see the same - arrangement. + arrangement (shown below). + + \image rgbController-final-layout.png \note Main layouts cannot be seen on the form. To check if you have a main layout installed, try resizing your form; your widgets should resize @@ -495,7 +488,6 @@ pressing \key{F4} or something \gui{Edit Signals/Slots} from the \gui{Edit} menu. - \omit \table \row \i \inlineimage rgbController-signalsAndSlots.png @@ -505,11 +497,8 @@ \gui{Configure Connection} dialog, shown below, will pop up. Select the correct signal and slot and click \gui OK. \endtable - \endomit - \omit \image rgbController-configureConnection.png - \endomit Repeat the step (in reverse order), clicking on the spin box and dragging the cursor towards the slider, to connect the spin box's diff --git a/doc/src/images/rgbController-final-layout.png b/doc/src/images/rgbController-final-layout.png new file mode 100644 index 0000000..d32a93e Binary files /dev/null and b/doc/src/images/rgbController-final-layout.png differ diff --git a/doc/src/images/rgbController-form-gridLayout.png b/doc/src/images/rgbController-form-gridLayout.png new file mode 100644 index 0000000..c8f3dcf Binary files /dev/null and b/doc/src/images/rgbController-form-gridLayout.png differ diff --git a/doc/src/images/rgbController-selectForLayout.png b/doc/src/images/rgbController-selectForLayout.png new file mode 100644 index 0000000..7a8e184 Binary files /dev/null and b/doc/src/images/rgbController-selectForLayout.png differ -- cgit v0.12 From aec18b0eea741da58a02f7ad95ab5ee9dccfce6c Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Tue, 26 May 2009 13:44:35 +0200 Subject: Doc - whitespace cleaning --- doc/src/designer-manual.qdoc | 48 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index 452782f..9c13d79 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -299,12 +299,12 @@ \row \i \inlineimage designer-widget-box.png \i \bold{Qt Designer's Widget Box} - + The widget box provides a selection of standard Qt widgets, layouts, and other objects that can be used to create user interfaces on forms. Each of the categories in the widget box contain widgets with similar uses or related features. - + \note Since Qt 4.4, new widgets have been included, e.g., QPlainTextEdit, QCommandLinkButton, QScrollArea, QMdiArea, and QWebView. @@ -358,7 +358,7 @@ using a grid. The coordinates on the screenshot show the position of each widget within the grid. - \image addressbook-tutorial-part3-labeled-layout.png + \image addressbook-tutorial-part3-labeled-layout.png \note Inside the grid, the QPushButton objects are actually nested. The buttons on the right are first placed in a QVBoxLayout; the buttons at the @@ -367,7 +367,7 @@ To visualize, imagine the layout as a box that shrinks as much as possible, attempting to \e squeeze your widgets in a neat arrangement, and, at the - same time, maximize the use of available space. + same time, maximize the use of available space. Qt's layouts help when you: @@ -446,7 +446,7 @@ form. To change the label's default text, simply double-click on it. You can arrange them according to how you would like them to be laid out. \endtable - + To ensure that they are laid out exactly like this in your program, you need to place these widgets into a layout. We will do this in groups of three. Select the "RED" label. Then, hold down \key Ctrl while you select @@ -779,11 +779,11 @@ have a \c text property that can also be edited by double-clicking on the widget or by pressing \gui F2. \QD interprets the backslash (\\) character specially, enabling newline (\\n) characters to be - inserted into the text; the \\\\ character sequence is used to + inserted into the text; the \\\\ character sequence is used to insert a single backslash into the text. A context menu can also be opened while editing, providing another way to insert special characters and newlines into the text. - \endlist + \endlist \section2 Dynamic Properties @@ -795,12 +795,12 @@ \image designer-property-editor-toolbar.png - To add a dynamic property, clcik on the \gui Add button + To add a dynamic property, clcik on the \gui Add button \inlineimage designer-property-editor-add-dynamic.png - . To remove it, click on the \gui Remove button + . To remove it, click on the \gui Remove button \inlineimage designer-property-editor-remove-dynamic.png instead. You can also sort the properties alphabetically and change the - color groups by clickinig on the \gui Configure button + color groups by clickinig on the \gui Configure button \inlineimage designer-property-editor-configure.png . @@ -902,7 +902,7 @@ \section2 Horizontal and Vertical Layouts - + The simplest way to arrange objects on a form is to place them in a horizontal or vertical layout. Horizontal layouts ensure that the widgets within are aligned horizontally; vertical layouts ensure that they are @@ -1129,7 +1129,7 @@ spacers just provide spacing hints to layouts, so they cannot be connected to other objects. - + \target HighlightedObjects \table \row @@ -1168,7 +1168,7 @@ \image designer-connection-dialog.png - To complete the connection, select a signal from the source object and a + To complete the connection, select a signal from the source object and a slot from the destination object, then click \key OK. Click \key Cancel if you wish to abandon the connection. @@ -1711,22 +1711,22 @@ \i \bold{Resource Files} Within the resource browser, you can open existing resource files or - create new ones. Click the \gui{Edit Resources} button + create new ones. Click the \gui{Edit Resources} button \inlineimage designer-edit-resources-button.png to edit your resources. To reload resources, click on the \gui Reload - button + button \inlineimage designer-reload-resources-button.png . \endtable Once a resource file is loaded, you can create or remove entries in it - using the given \gui{Add Files} - \inlineimage designer-add-resource-entry-button.png - and \gui{Remove Files} + using the given \gui{Add Files} + \inlineimage designer-add-resource-entry-button.png + and \gui{Remove Files} \inlineimage designer-remove-resource-entry-button.png buttons, and specify resources (e.g., images) using the \gui{Add Files} - button + button \inlineimage designer-add-files-button.png . Note that these resources must reside within the current resource file's directory or one of its subdirectories. @@ -1738,15 +1738,15 @@ \i \inlineimage designer-edit-resource.png \i \bold{Editing Resource Files} - Press the + Press the \inlineimage designer-add-resource-entry-button.png button to add a new resource entry to the file. Then use the - \gui{Add Files} button + \gui{Add Files} button \inlineimage designer-add-files-button.png to specify the resource. You can remove resources by selecting the corresponding entry in the - resource editor, and pressing the + resource editor, and pressing the \inlineimage designer-remove-resource-entry-button.png button. \endtable @@ -2554,7 +2554,7 @@ pixmap property in the property editor. QDesignerTaskMenuExtension is useful for custom widgets. It provides an extension that allows you to add custom menu entries to \QD's task menu. - + The \l{designer/taskmenuextension}{Task Menu Extension} example illustrates how to use this class. @@ -2655,7 +2655,7 @@ pixmap property in the property editor. function, making it able to create your extension, such as a \l{designer/containerextension}{MultiPageWidget} container extension. - You can either create a new QExtensionFactory and reimplement the + You can either create a new QExtensionFactory and reimplement the QExtensionFactory::createExtension() function: \snippet doc/src/snippets/code/doc_src_designer-manual.qdoc 8 -- cgit v0.12 From 2c8348f5ccf62be31479dcd78282395a98eed76f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 26 May 2009 14:13:21 +0200 Subject: BT: opening datetimepicker in a cell in spreadsheet demo resets the date That was a bug in the exemple. Reviewed-by: Kavindra Palaraja --- demos/spreadsheet/spreadsheetdelegate.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/demos/spreadsheet/spreadsheetdelegate.cpp b/demos/spreadsheet/spreadsheetdelegate.cpp index 465c92f..2916757 100644 --- a/demos/spreadsheet/spreadsheetdelegate.cpp +++ b/demos/spreadsheet/spreadsheetdelegate.cpp @@ -51,7 +51,7 @@ QWidget *SpreadSheetDelegate::createEditor(QWidget *parent, { if (index.column() == 1) { QDateTimeEdit *editor = new QDateTimeEdit(parent); - editor->setDisplayFormat("dd/M/yyy"); + editor->setDisplayFormat("dd/M/yyyy"); editor->setCalendarPopup(true); return editor; } @@ -93,7 +93,7 @@ void SpreadSheetDelegate::setEditorData(QWidget *editor, if (dateEditor) { dateEditor->setDate(QDate::fromString( index.model()->data(index, Qt::EditRole).toString(), - "d/M/yy")); + "d/M/yyyy")); } } } @@ -107,7 +107,7 @@ void SpreadSheetDelegate::setModelData(QWidget *editor, } else { QDateTimeEdit *dateEditor = qobject_cast(editor); if (dateEditor) { - model->setData(index, dateEditor->date().toString("dd/M/yyy")); + model->setData(index, dateEditor->date().toString("dd/M/yyyy")); } } } -- cgit v0.12 From 1536b02ed1633555e306bec02398a2a7c1bdabf7 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 26 May 2009 14:19:27 +0200 Subject: Test for QDate::fromDate with string format. Note that two digit years are always in the year 19xx This is excepted for compatibility reason as discussed with Peter --- tests/auto/qdate/tst_qdate.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/auto/qdate/tst_qdate.cpp b/tests/auto/qdate/tst_qdate.cpp index d4273d0..4d6c80c 100644 --- a/tests/auto/qdate/tst_qdate.cpp +++ b/tests/auto/qdate/tst_qdate.cpp @@ -82,6 +82,8 @@ private slots: void operator_gt_eq(); void fromString_data(); void fromString(); + void fromString_format_data(); + void fromString_format(); void toString_format_data(); void toString_format(); void isLeapYear(); @@ -618,6 +620,30 @@ void tst_QDate::fromString() QCOMPARE( QDate::fromString( str2, Qt::ISODate ), d1 ); } +void tst_QDate::fromString_format_data() +{ + QTest::addColumn("string"); + QTest::addColumn("format"); + QTest::addColumn("date"); + + //year with yy is always 19xx for compatibility + QTest::newRow( "data0" ) << QString("21052006") << QString("ddMMyyyy") << QDate(2006,5,21); + QTest::newRow( "data1" ) << QString("210506") << QString("ddMMyy") << QDate(1906,5,21); + QTest::newRow( "data2" ) << QString("21/5/2006") << QString("d/M/yyyy") << QDate(2006,5,21); + QTest::newRow( "data3" ) << QString("21/5/06") << QString("d/M/yy") << QDate(1906,5,21); + QTest::newRow( "data4" ) << QString("20060521") << QString("yyyyMMdd") << QDate(2006,5,21); + QTest::newRow( "data5" ) << QString("060521") << QString("yyMMdd") << QDate(1906,5,21); +} + +void tst_QDate::fromString_format() +{ + QFETCH( QString, string ); + QFETCH( QString, format ); + QFETCH( QDate, date ); + + QCOMPARE( QDate::fromString( string, format ), date ); +} + void tst_QDate::toString_format_data() { QTest::addColumn("t"); -- cgit v0.12 From 8a2ca9b0d8ed23cec44e40f61c0f4983fbc55282 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Tue, 26 May 2009 14:06:56 +0200 Subject: Correcting bugs in classic.css Correcting invalid padding values. none is not a valid padding value. Rev-by: David Boddie --- tools/qdoc3/test/classic.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css index 6cf7377..f22a77a 100644 --- a/tools/qdoc3/test/classic.css +++ b/tools/qdoc3/test/classic.css @@ -77,10 +77,10 @@ table.annotated td { table tr pre { - padding-top: none; - padding-bottom: none; - padding-left: none; - padding-right: none; + padding-top: 0px; + padding-bottom: 0px; + padding-left: 0px; + padding-right: 0px; border: none; background: none } -- cgit v0.12 From 871b730da203cef773e159960532888522f16a0b Mon Sep 17 00:00:00 2001 From: Trond Kjernaasen Date: Tue, 26 May 2009 14:20:34 +0200 Subject: BT: Fixed GL textdrawing in the Boxes demo. Reworked the 85f98acaa3a38079071bea711e43c9a86edec1f6 fix, since it broke glyph positioning in the GL engine under Windows. Instead of changing the glyph cache margin, which impacts where the glyph is positioned, we just make the image the glyph is drawn into 4 pixels bigger in width/heigth. The margin in QImageTextureGlyphCache needs to be reworked.. Task-number: 254450 Reviewed-by: Eskil --- src/gui/painting/qtextureglyphcache.cpp | 8 ++++++-- src/gui/text/qfontengine_win.cpp | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 3fd1ffb..89df869 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -92,8 +92,8 @@ void QTextureGlyphCache::populate(const QTextItemInt &ti, int glyph_height = metrics.height.ceil().toInt(); if (glyph_height == 0 || glyph_width == 0) continue; - glyph_width += margin * 2 + 2; - glyph_height += margin * 2 + 2; + glyph_width += margin * 2 + 4; + glyph_height += margin * 2 + 4; // align to 8-bit boundary if (m_type == QFontEngineGlyphCache::Raster_Mono) glyph_width = (glyph_width+7)&~7; @@ -189,7 +189,11 @@ void QImageTextureGlyphCache::createTextureData(int width, int height) int QImageTextureGlyphCache::glyphMargin() const { +#ifdef Q_WS_MAC return 2; +#else + return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0; +#endif } void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g) diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index bf3a176..7341665 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -1406,8 +1406,8 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin #endif #endif - QNativeImage *ni = new QNativeImage(iw + 2 * margin + 2, - ih + 2 * margin + 2, + QNativeImage *ni = new QNativeImage(iw + 2 * margin + 4, + ih + 2 * margin + 4, QNativeImage::systemFormat(), true); ni->image.fill(0xffffffff); @@ -1449,7 +1449,7 @@ QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform) font = CreateFontIndirectW(&lf); } - QNativeImage *mask = drawGDIGlyph(font, glyph, 2, xform); + QNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform); if (mask == 0) return QImage(); -- cgit v0.12 From c17f27a9a14c353c6149f2c15f6a0ff6afe3dedd Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 26 May 2009 13:22:00 +0200 Subject: SSL: Remove broken system certificate loading code Task-number: 254365 Reviewed-by: Peter Hartmann --- src/network/ssl/qsslsocket_openssl.cpp | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 6f8cf42..cb101af 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -482,30 +482,7 @@ void QSslSocketPrivate::resetDefaultCiphers() QList QSslSocketPrivate::systemCaCertificates() { -#ifdef QQ_OS_UNIX - // Check known locations for the system's default bundle. ### On Windows, - // we should use CAPI to find the bundle, and not rely on default unix - // locations. - const char *standardLocations[] = {"/etc/ssl/certs/", -#if 0 - // KDE uses KConfig for its SSL store, - // but it also stores the bundle at - // this location - "$HOME/.kde/share/apps/kssl/ca-bundle.crt", -#endif - 0}; - const char **it = standardLocations; - QStringList nameFilter; - nameFilter << QLatin1String("*.pem") << QLatin1String("*.crt"); - while (*it) { - if (QDirIterator(QLatin1String(*it), nameFilter).hasNext()) - return certificatesFromPath(QLatin1String(*it)); - ++it; - } -#endif - - // Qt provides a default bundle when we cannot detect the system's default - // bundle. + // Qt provides a default bundle of certificates QFile caBundle(QLatin1String(":/trolltech/network/ssl/qt-ca-bundle.crt")); if (caBundle.open(QIODevice::ReadOnly | QIODevice::Text)) return QSslCertificate::fromDevice(&caBundle); -- cgit v0.12 From a670315152bf0914b8661b584d20752fd4da5b95 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 26 May 2009 14:40:40 +0200 Subject: A GLint is converted to int for passing to qBound(). --- src/opengl/qglframebufferobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 2b7ad4f..338ce1f 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -395,7 +395,7 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At GLint maxSamples; glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); - samples = qBound(1, samples, int(maxSamples)); + samples = qBound(1, int(samples), int(maxSamples)); glGenRenderbuffers(1, &color_buffer); glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer); -- cgit v0.12 From 7c383fc79510276439deeb706d48ad5543fb54e7 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 26 May 2009 14:46:15 +0200 Subject: Fix a painting issue in the QGtkStyle statusbar We should use the "statusbar" string when we draw the sizegrip. Since gtkstatusbar is the only gtk widget using the paint_resize_grip and it uses the "statusbar" string itself it should be safe to assume this. Task-number: 254535 Reviewed-by: rosch --- src/gui/styles/qgtkstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 86653df..14be518 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2344,7 +2344,7 @@ void QGtkStyle::drawControl(ControlElement element, case CE_SizeGrip: { GtkWidget *gtkStatusbar = QGtk::gtkWidget(QLS("GtkStatusbar.GtkFrame")); QRect gripRect = option->rect.adjusted(0, 0, -gtkStatusbar->style->xthickness, -gtkStatusbar->style->ythickness); - gtkPainter.paintResizeGrip( gtkStatusbar, "window", gripRect, GTK_STATE_NORMAL, + gtkPainter.paintResizeGrip( gtkStatusbar, "statusbar", gripRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, QApplication::isRightToLeft() ? GDK_WINDOW_EDGE_SOUTH_WEST : GDK_WINDOW_EDGE_SOUTH_EAST, gtkStatusbar->style); -- cgit v0.12 From 0ae04e9d7872d170974d15e8fbae8da1949c94df Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 26 May 2009 15:33:47 +0200 Subject: Mac: Prefix sat in qt.conf is ignored on Mac Fix: Make sure to add the prefix to the value we return in QLibraryInfo Task-number: 254545 Reviewed-by: Trenton Schulz --- src/corelib/global/qlibraryinfo.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 29e356e..7f6ff20 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -434,14 +434,14 @@ QLibraryInfo::location(LibraryLocation loc) #else if (QCoreApplication::instance()) { #ifdef Q_OS_MAC - CFBundleRef bundleRef = CFBundleGetMainBundle(); - if (bundleRef) { - QCFType urlRef = CFBundleCopyBundleURL(bundleRef); - if (urlRef) { - QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle); - return QDir::cleanPath(path + QLatin1String("/Contents")); - } - } + CFBundleRef bundleRef = CFBundleGetMainBundle(); + if (bundleRef) { + QCFType urlRef = CFBundleCopyBundleURL(bundleRef); + if (urlRef) { + QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle); + return QDir::cleanPath(path + QLatin1String("/Contents/") + ret); + } + } #endif return QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(ret); } else { -- cgit v0.12 From 1164e61393349fc3d6bf06d0789fa6ea2cfb5909 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Tue, 26 May 2009 15:37:45 +0200 Subject: Doc - more images and additional description --- doc/src/designer-manual.qdoc | 24 +++++++++++---------- .../images/rgbController-configure-connection1.png | Bin 0 -> 29210 bytes .../images/rgbController-configure-connection2.png | Bin 0 -> 28655 bytes doc/src/images/rgbController-property-editing.png | Bin 0 -> 9158 bytes doc/src/images/rgbController-screenshot.png | Bin 0 -> 8995 bytes doc/src/images/rgbController-signalsAndSlots.png | Bin 0 -> 10050 bytes 6 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 doc/src/images/rgbController-configure-connection1.png create mode 100644 doc/src/images/rgbController-configure-connection2.png create mode 100644 doc/src/images/rgbController-property-editing.png create mode 100644 doc/src/images/rgbController-screenshot.png create mode 100644 doc/src/images/rgbController-signalsAndSlots.png diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index 9c13d79..58d0f71 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -478,11 +478,12 @@ accordingly. When you click on the slider and drag it to a certain value, you want the - spin box to display the slider's position. To do this, you need to connect - the slider's \l{QAbstractSlider::}{valueChanged()} signal to the spin box's - \l{QSpinBox::}{setValue()} slot. You also need to make the reverse - connections, e.g., connect the spin box's \l{QSpinBox::}{valueChanged()} - signal to the slider's \l{QAbstractSlider::value()}{setValue()} slot. + spin box to display the slider's position. To accomplish this behavior, you + need to connect the slider's \l{QAbstractSlider::}{valueChanged()} signal + to the spin box's \l{QSpinBox::}{setValue()} slot. You also need to make + the reverse connections, e.g., connect the spin box's \l{QSpinBox::} + {valueChanged()} signal to the slider's \l{QAbstractSlider::value()} + {setValue()} slot. To do this, you have to switch to \gui{Edit Signals/Slots} mode, either by pressing \key{F4} or something \gui{Edit Signals/Slots} from the \gui{Edit} @@ -498,13 +499,18 @@ correct signal and slot and click \gui OK. \endtable - \image rgbController-configureConnection.png + \image rgbController-configureConnection1.png Repeat the step (in reverse order), clicking on the spin box and dragging the cursor towards the slider, to connect the spin box's \l{QSpinBox::}{valueChanged()} signal to the slider's \l{QAbstractSlider::value()}{setValue()} slot. + You can use the screenshot below as a guide to selecting the correct signal + and slot. + + \image rgbController-configure-connection2.png + Now that you have successfully connected the objects for the "RED" component of the RGB Controller, do the same for the "GREEN" and "BLUE" components as well. @@ -512,7 +518,6 @@ Since RGB values range between 0 and 255, we need to limit the spin box and slider to that particular range. - \omit \table \row \i \inlineimage rgbController-property-editing.png @@ -523,17 +528,14 @@ \l{QSpinBox::}{maximum} property. Then, click on the first vertical slider, you will see \l{QAbstractSlider}'s properties. Enter "255" for the \l{QAbstractSlider::}{maximum} property as well. Repeat this - process for the remaining spin boxes and sliders. + process for the remaining spin boxes and sliders. \endtable - \endomit Now, we preview your form to see how it would look in your application. To preview your form, press \key{Ctrl + R} or select \gui Preview from the \gui Form menu. - \omit \image rgbController-preview.png - \endomit Try dragging the slider - the spin box will mirror its value too (and vice versa). Also, you can resize it to see how the layouts used to manage the diff --git a/doc/src/images/rgbController-configure-connection1.png b/doc/src/images/rgbController-configure-connection1.png new file mode 100644 index 0000000..0798184 Binary files /dev/null and b/doc/src/images/rgbController-configure-connection1.png differ diff --git a/doc/src/images/rgbController-configure-connection2.png b/doc/src/images/rgbController-configure-connection2.png new file mode 100644 index 0000000..f3fcc62 Binary files /dev/null and b/doc/src/images/rgbController-configure-connection2.png differ diff --git a/doc/src/images/rgbController-property-editing.png b/doc/src/images/rgbController-property-editing.png new file mode 100644 index 0000000..64fc500 Binary files /dev/null and b/doc/src/images/rgbController-property-editing.png differ diff --git a/doc/src/images/rgbController-screenshot.png b/doc/src/images/rgbController-screenshot.png new file mode 100644 index 0000000..6019233 Binary files /dev/null and b/doc/src/images/rgbController-screenshot.png differ diff --git a/doc/src/images/rgbController-signalsAndSlots.png b/doc/src/images/rgbController-signalsAndSlots.png new file mode 100644 index 0000000..2ba3aba Binary files /dev/null and b/doc/src/images/rgbController-signalsAndSlots.png differ -- cgit v0.12 From a088a3e5698881b0466cd072380fc7347ea68fba Mon Sep 17 00:00:00 2001 From: kh Date: Tue, 26 May 2009 15:53:52 +0200 Subject: Fix broken search inside search results. Reviewed-by: kh --- tools/assistant/tools/assistant/centralwidget.cpp | 131 ++++++++++------------ tools/assistant/tools/assistant/centralwidget.h | 5 +- 2 files changed, 66 insertions(+), 70 deletions(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index b78f346..98245c0 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -848,60 +848,64 @@ void CentralWidget::keyPressEvent(QKeyEvent *e) QWidget::keyPressEvent(e); } -void CentralWidget::find(QString ttf, bool forward, bool backward) +void CentralWidget::find(const QString &ttf, bool forward, bool backward) { - QTextCursor cursor; - QTextDocument *doc = 0; - QTextBrowser *browser = 0; - - HelpViewer *viewer = currentHelpViewer(); QPalette p = findWidget->editFind->palette(); p.setColor(QPalette::Active, QPalette::Base, Qt::white); -#if !defined(QT_NO_WEBKIT) - Q_UNUSED(forward) - Q_UNUSED(doc) - Q_UNUSED(browser) - - if (viewer) { - QWebPage::FindFlags options; - if (backward) - options |= QWebPage::FindBackward; + if (!ttf.isEmpty()) { + HelpViewer *viewer = currentHelpViewer(); - if (findWidget->checkCase->isChecked()) - options |= QWebPage::FindCaseSensitively; + bool found = false; +#if !defined(QT_NO_WEBKIT) + if (viewer) { + QWebPage::FindFlags options; + if (backward) + options |= QWebPage::FindBackward; - bool found = viewer->findText(ttf, options); - findWidget->labelWrapped->hide(); + if (findWidget->checkCase->isChecked()) + options |= QWebPage::FindCaseSensitively; - if (!found) { - options |= QWebPage::FindWrapsAroundDocument; found = viewer->findText(ttf, options); + findWidget->labelWrapped->hide(); if (!found) { - p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102)); - } else { - findWidget->labelWrapped->show(); + options |= QWebPage::FindWrapsAroundDocument; + found = viewer->findText(ttf, options); + if (found) + findWidget->labelWrapped->show(); } + } else if (tabWidget->currentWidget() == m_searchWidget) { + QTextBrowser *browser = qFindChild(m_searchWidget); + found = findInTextBrowser(browser, ttf, forward, backward); } - } #else - if (viewer) { - doc = viewer->document(); - cursor = viewer->textCursor(); - browser = qobject_cast(viewer); - } + QTextBrowser *browser = qobject_cast(viewer); + if (tabWidget->currentWidget() == m_searchWidget) + browser = qFindChild(m_searchWidget); + found = findInTextBrowser(browser, ttf, forward, backward); +#endif - if (tabWidget->currentWidget() == m_searchWidget) { - QTextBrowser *browser = qFindChild(m_searchWidget); - if (browser) { - doc = browser->document(); - cursor = browser->textCursor(); - } + if (!found) + p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102)); } - if (!browser || !doc || cursor.isNull()) - return; + if (!findWidget->isVisible()) + findWidget->show(); + findWidget->editFind->setPalette(p); +} + +bool CentralWidget::findInTextBrowser(QTextBrowser* browser, const QString &ttf, + bool forward, bool backward) +{ + if (!browser) + return false; + + QTextDocument *doc = browser->document(); + QTextCursor cursor = browser->textCursor(); + + if (!doc || cursor.isNull()) + return false; QTextDocument::FindFlags options; @@ -910,44 +914,33 @@ void CentralWidget::find(QString ttf, bool forward, bool backward) QTextCursor::MoveAnchor); } - QTextCursor newCursor = cursor; + if (backward) + options |= QTextDocument::FindBackward; - if (!ttf.isEmpty()) { - if (backward) - options |= QTextDocument::FindBackward; - - if (findWidget->checkCase->isChecked()) - options |= QTextDocument::FindCaseSensitively; + if (findWidget->checkCase->isChecked()) + options |= QTextDocument::FindCaseSensitively; - if (findWidget->checkWholeWords->isChecked()) - options |= QTextDocument::FindWholeWords; + if (findWidget->checkWholeWords->isChecked()) + options |= QTextDocument::FindWholeWords; - newCursor = doc->find(ttf, cursor, options); - findWidget->labelWrapped->hide(); + findWidget->labelWrapped->hide(); + bool found = true; + QTextCursor newCursor = doc->find(ttf, cursor, options); + if (newCursor.isNull()) { + QTextCursor ac(doc); + ac.movePosition(options & QTextDocument::FindBackward + ? QTextCursor::End : QTextCursor::Start); + newCursor = doc->find(ttf, ac, options); if (newCursor.isNull()) { - QTextCursor ac(doc); - ac.movePosition(options & QTextDocument::FindBackward - ? QTextCursor::End : QTextCursor::Start); - newCursor = doc->find(ttf, ac, options); - if (newCursor.isNull()) { - p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102)); - newCursor = cursor; - } else { - findWidget->labelWrapped->show(); - } + found = false; + newCursor = cursor; + } else { + findWidget->labelWrapped->show(); } } -#endif - - if (!findWidget->isVisible()) - findWidget->show(); - -#if defined(QT_NO_WEBKIT) - if (browser) - browser->setTextCursor(newCursor); -#endif - findWidget->editFind->setPalette(p); + browser->setTextCursor(newCursor); + return found; } void CentralWidget::updateBrowserFont() diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h index e3ce200..1342a75 100644 --- a/tools/assistant/tools/assistant/centralwidget.h +++ b/tools/assistant/tools/assistant/centralwidget.h @@ -55,6 +55,7 @@ class QLabel; class QAction; class QCheckBox; class QLineEdit; +class QTextBrowser; class QToolButton; class HelpViewer; @@ -176,7 +177,9 @@ private slots: private: void connectSignals(); bool eventFilter(QObject *object, QEvent *e); - void find(QString ttf, bool forward, bool backward); + void find(const QString &ttf, bool forward, bool backward); + bool findInTextBrowser(QTextBrowser* browser, const QString &ttf, + bool forward, bool backward); void initPrinter(); QString quoteTabTitle(const QString &title) const; void highlightSearchTerms(); -- cgit v0.12 From b03f598df2aa4037815eab9249ba1213236216c5 Mon Sep 17 00:00:00 2001 From: kh Date: Tue, 26 May 2009 15:57:45 +0200 Subject: Workaround the palette issue, set it only when we search is open. --- tools/assistant/tools/assistant/centralwidget.cpp | 35 +++++++++++++++++++++-- tools/assistant/tools/assistant/centralwidget.h | 5 ++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 98245c0..52d48d5 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -87,6 +87,7 @@ namespace { FindWidget::FindWidget(QWidget *parent) : QWidget(parent) + , appPalette(qApp->palette()) { QHBoxLayout *hboxLayout = new QHBoxLayout(this); QString resourcePath = QLatin1String(":/trolltech/assistant/images/"); @@ -148,6 +149,34 @@ FindWidget::~FindWidget() { } +void FindWidget::hideEvent(QHideEvent* event) +{ +#if !defined(QT_NO_WEBKIT) + // TODO: remove this once webkit supports setting the palette + if (!event->spontaneous()) + qApp->setPalette(appPalette); +#else + Q_UNUSED(event); +#endif +} + +void FindWidget::showEvent(QShowEvent* event) +{ +#if !defined(QT_NO_WEBKIT) + // TODO: remove this once webkit supports setting the palette + if (!event->spontaneous()) { + QPalette p = appPalette; + p.setColor(QPalette::Inactive, QPalette::Highlight, + p.color(QPalette::Active, QPalette::Highlight)); + p.setColor(QPalette::Inactive, QPalette::HighlightedText, + p.color(QPalette::Active, QPalette::HighlightedText)); + qApp->setPalette(p); + } +#else + Q_UNUSED(event); +#endif +} + void FindWidget::updateButtons() { if (editFind->text().isEmpty()) { @@ -245,12 +274,14 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent) SLOT(showTabBarContextMenu(QPoint))); } - QPalette p = qApp->palette(); +#if defined(QT_NO_WEBKIT) + QPalette p = palette(); p.setColor(QPalette::Inactive, QPalette::Highlight, p.color(QPalette::Active, QPalette::Highlight)); p.setColor(QPalette::Inactive, QPalette::HighlightedText, p.color(QPalette::Active, QPalette::HighlightedText)); - qApp->setPalette(p); + setPalette(p); +#endif } CentralWidget::~CentralWidget() diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h index 1342a75..d59dbe5 100644 --- a/tools/assistant/tools/assistant/centralwidget.h +++ b/tools/assistant/tools/assistant/centralwidget.h @@ -80,6 +80,10 @@ signals: void findNext(); void findPrevious(); +protected: + void hideEvent(QHideEvent* event); + void showEvent(QShowEvent * event); + private slots: void updateButtons(); @@ -95,6 +99,7 @@ private: QToolButton *toolPrevious; QCheckBox *checkWholeWords; + QPalette appPalette; friend class CentralWidget; }; -- cgit v0.12 From f61056a556259c12a6de23f12756e45737345111 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 26 May 2009 16:08:59 +0200 Subject: Doc: Updated the list of tools to include makeqpf and qvfb. Reviewed-by: Marcel Schuette --- doc/src/emb-fonts.qdoc | 2 +- doc/src/emb-makeqpf.qdoc | 9 ++++++--- doc/src/tools-list.qdoc | 6 ++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/src/emb-fonts.qdoc b/doc/src/emb-fonts.qdoc index 3ed23c3..86e169d 100644 --- a/doc/src/emb-fonts.qdoc +++ b/doc/src/emb-fonts.qdoc @@ -131,7 +131,7 @@ The Qt Prerendered Font (QPF2) is an architecture-independent, light-weight and non-scalable font format specific to \l{Qt for Embedded Linux}. - Nokia provides the cross-platform \c makeqpf tool, included in the + Nokia provides the cross-platform \l makeqpf tool, included in the \c tools directory of both \l {Qt} and \l{Qt for Embedded Linux}, which allows generation of QPF2 files from system fonts. diff --git a/doc/src/emb-makeqpf.qdoc b/doc/src/emb-makeqpf.qdoc index ca33eda..8f5d10b 100644 --- a/doc/src/emb-makeqpf.qdoc +++ b/doc/src/emb-makeqpf.qdoc @@ -44,7 +44,10 @@ \title makeqpf \ingroup qt-embedded-linux - \c makeqpf is not part of Qt 4. However, Qt 4 can still read QPF - files generated by Qt 2 or 3. To generate QPF files, use makeqpf from Qt 2 - or 3. + \c makeqpf is a tool to generate pre-rendered fonts in QPF2 format for use on Embedded Linux. + + Qt 4 can read files in QPF2 format in addition to QPF files generated by older versions of + \c makeqpf from Qt 2 or 3. + + \sa {Qt for Embedded Linux Fonts} */ diff --git a/doc/src/tools-list.qdoc b/doc/src/tools-list.qdoc index 7af9936..caef268 100644 --- a/doc/src/tools-list.qdoc +++ b/doc/src/tools-list.qdoc @@ -58,12 +58,10 @@ \o Translate applications to reach international markets. \row \o \l{qmake Manual}{qmake} \o Create makefiles from simple platform-independent project files (\c .pro files). - \omit - \row \o \l{emb-qvfb.html}{qvfb} + \row \o \l{The Virtual Framebuffer}{qvfb} \o Run and test embedded applications on the desktop. - \row \o \l{emb-makeqpf.html}{makeqpf} + \row \o \l{makeqpf} \o Create pre-rendered fonts for embedded devices. - \endomit \row \o \l{moc}{Meta-Object Compiler (moc)} \o Generate meta-object information for QObject subclasses. \row \o \l{User Interface Compiler (uic)} -- cgit v0.12 From bcd23411c8e22e15b863212a544bd64b78fe04b9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 26 May 2009 17:13:57 +0200 Subject: some cleanups on private exported symbols --- src/gui/accessible/qaccessiblewidget.cpp | 19 +------------------ src/gui/image/qpixmapdatafactory_p.h | 2 +- src/gui/kernel/qapplication_win.cpp | 2 +- src/gui/kernel/qdnd_p.h | 2 +- src/gui/kernel/qkeysequence.cpp | 2 +- src/gui/painting/qgraphicssystemfactory_p.h | 2 +- src/gui/painting/qgraphicssystemplugin_p.h | 2 +- src/gui/text/qfontengine.cpp | 6 ------ src/gui/text/qfontengine_p.h | 6 ++++-- src/gui/text/qtextcontrol_p.h | 2 +- src/gui/text/qtextimagehandler_p.h | 4 ++-- src/opengl/qpaintengine_opengl.cpp | 1 - src/qt3support/other/q3dragobject.cpp | 5 ----- 13 files changed, 14 insertions(+), 41 deletions(-) diff --git a/src/gui/accessible/qaccessiblewidget.cpp b/src/gui/accessible/qaccessiblewidget.cpp index 753ac57..1c2fcef 100644 --- a/src/gui/accessible/qaccessiblewidget.cpp +++ b/src/gui/accessible/qaccessiblewidget.cpp @@ -102,24 +102,7 @@ static QString buddyString(const QWidget *widget) QString Q_GUI_EXPORT qt_accStripAmp(const QString &text) { - if (text.isEmpty()) - return text; - - const QChar *ch = text.unicode(); - int length = text.length(); - QString str; - while (length > 0) { - if (*ch == QLatin1Char('&')) { - ++ch; - --length; - if (!ch) - --ch; - } - str += *ch; - ++ch; - --length; - } - return str; + return QString(text).remove(QLatin1Char('&')); } QString Q_GUI_EXPORT qt_accHotKey(const QString &text) diff --git a/src/gui/image/qpixmapdatafactory_p.h b/src/gui/image/qpixmapdatafactory_p.h index 65e3f11..9604346 100644 --- a/src/gui/image/qpixmapdatafactory_p.h +++ b/src/gui/image/qpixmapdatafactory_p.h @@ -65,7 +65,7 @@ QT_MODULE(Gui) class QPixmapData; -class Q_GUI_EXPORT QPixmapDataFactory +class QPixmapDataFactory { public: static QPixmapDataFactory* instance(int screen = 0); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 77625de..f264d12 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -1106,7 +1106,7 @@ void qWinRequestConfig(WId id, int req, int x, int y, int w, int h) configRequests->append(r); // store request in queue } -Q_GUI_EXPORT void qWinProcessConfigRequests() // perform requests in queue +static void qWinProcessConfigRequests() // perform requests in queue { if (!configRequests) return; diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h index 7a0cb7a..9871658 100644 --- a/src/gui/kernel/qdnd_p.h +++ b/src/gui/kernel/qdnd_p.h @@ -202,7 +202,7 @@ public: #endif }; -class Q_GUI_EXPORT QDragManager: public QObject { +class QDragManager: public QObject { Q_OBJECT QDragManager(); diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index d1cb572..21f8859 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -145,7 +145,7 @@ static int qtkeyForMacSymbol(const QChar ch) #else static bool qt_sequence_no_mnemonics = false; #endif -void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; } +void Q_AUTOTEST_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; } /*! \class QKeySequence diff --git a/src/gui/painting/qgraphicssystemfactory_p.h b/src/gui/painting/qgraphicssystemfactory_p.h index 9e95324..523b908 100644 --- a/src/gui/painting/qgraphicssystemfactory_p.h +++ b/src/gui/painting/qgraphicssystemfactory_p.h @@ -63,7 +63,7 @@ QT_MODULE(Gui) class QGraphicsSystem; -class Q_GUI_EXPORT QGraphicsSystemFactory +class QGraphicsSystemFactory { public: static QStringList keys(); diff --git a/src/gui/painting/qgraphicssystemplugin_p.h b/src/gui/painting/qgraphicssystemplugin_p.h index 2e70333..ea7aa2d 100644 --- a/src/gui/painting/qgraphicssystemplugin_p.h +++ b/src/gui/painting/qgraphicssystemplugin_p.h @@ -64,7 +64,7 @@ QT_MODULE(Gui) class QGraphicsSystem; -struct Q_GUI_EXPORT QGraphicsSystemFactoryInterface : public QFactoryInterface +struct QGraphicsSystemFactoryInterface : public QFactoryInterface { virtual QGraphicsSystem *create(const QString &key) = 0; }; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 97cb1ed..6e8adcf 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1646,12 +1646,6 @@ bool QFontEngineMulti::canRender(const QChar *string, int len) return allExist; } -QFontEngine *QFontEngineMulti::engine(int at) const -{ - Q_ASSERT(at < engines.size()); - return engines.at(at); -} - QImage QFontEngineMulti::alphaMapForGlyph(glyph_t) { Q_ASSERT(false); diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 92efb6c..0f8d81c 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -353,7 +353,7 @@ private: int _size; }; -class Q_GUI_EXPORT QFontEngineMulti : public QFontEngine +class QFontEngineMulti : public QFontEngine { public: explicit QFontEngineMulti(int engineCount); @@ -389,7 +389,9 @@ public: inline virtual const char *name() const { return "Multi"; } - QFontEngine *engine(int at) const; + QFontEngine *engine(int at) const + {Q_ASSERT(at < engines.size()); return engines.at(at); } + protected: friend class QPSPrintEnginePrivate; diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h index e50540a..4dac4f7 100644 --- a/src/gui/text/qtextcontrol_p.h +++ b/src/gui/text/qtextcontrol_p.h @@ -83,7 +83,7 @@ class QAbstractScrollArea; class QEvent; class QTimerEvent; -class Q_GUI_EXPORT QTextControl : public QObject +class Q_AUTOTEST_EXPORT QTextControl : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QTextControl) diff --git a/src/gui/text/qtextimagehandler_p.h b/src/gui/text/qtextimagehandler_p.h index f5426b5..1f29642 100644 --- a/src/gui/text/qtextimagehandler_p.h +++ b/src/gui/text/qtextimagehandler_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class QTextImageFormat; -class Q_GUI_EXPORT QTextImageHandler : public QObject, +class QTextImageHandler : public QObject, public QTextObjectInterface { Q_OBJECT @@ -72,7 +72,7 @@ public: virtual void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format); typedef QImage (*ExternalImageLoaderFunction)(const QString &name, const QString &context); - static ExternalImageLoaderFunction externalLoader; + static Q_GUI_EXPORT ExternalImageLoaderFunction externalLoader; //this is needed by Qt3Support }; QT_END_NAMESPACE diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 6f7078a..d98cd7c 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ -#include #include #include #include diff --git a/src/qt3support/other/q3dragobject.cpp b/src/qt3support/other/q3dragobject.cpp index fb57220..50b75a4 100644 --- a/src/qt3support/other/q3dragobject.cpp +++ b/src/qt3support/other/q3dragobject.cpp @@ -208,11 +208,6 @@ void Q3DragObject::setPixmap(QPixmap pm, const QPoint& hotspot) Q_D(Q3DragObject); d->pixmap = pm; d->hot = hotspot; -#if 0 - QDragManager *manager = QDragManager::self(); - if (manager && manager->object == d->data) - manager->updatePixmap(); -#endif } /*! -- cgit v0.12 From 702a50367b13a137a9a87b499e4ab397be61383a Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 26 May 2009 16:26:33 +0200 Subject: doc update no more warnings while generating the docs --- src/gui/graphicsview/qgraphicsitem.cpp | 176 ++++++++++++++++++++++++------- src/gui/graphicsview/qgraphicswidget.cpp | 50 ++++++++- 2 files changed, 186 insertions(+), 40 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 0398fac..58b01cb 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -130,7 +130,7 @@ \img graphicsview-parentchild.png - \section Transformation + \section1 Transformation QGraphicsItem supports affine transformations in addition to its base position, pos(). To change the item's transformation, you can either pass @@ -166,7 +166,7 @@ .shear(horizontalShear, verticalShear).scale(xScale, yScale).translate(-xOrigin, -yOrigin); \endcode - \section Painting + \section1 Painting The paint() function is called by QGraphicsView to paint the item's contents. The item has no background or default fill of its own; whatever @@ -183,7 +183,7 @@ high z-values. Stacking order applies to sibling items; parents are always drawn before their children. - \section Events + \section1 Events QGraphicsItem receives events from QGraphicsScene through the virtual function sceneEvent(). This function distributes the most common events @@ -210,7 +210,7 @@ by the virtual function sceneEventFilter(). You can remove item event filters by calling removeSceneEventFilter(). - \section Custom Data + \section1 Custom Data Sometimes it's useful to register custom data with an item, be it a custom item, or a standard item. You can call setData() on any item to store data @@ -2614,24 +2614,32 @@ QTransform QGraphicsItem::transform() const } /*! - \property QGraphicsItem::xRotation - \since 4.6 - This property holds the rotation angle in degrees around the X axis + Returns the rotation around the X axis. The default is 0 \warning setting this property is conflicting with calling setTransform. If a transform has been set, this function return the default value. - \sa {Transformations} + \sa setXRotation(), {Transformations} */ qreal QGraphicsItem::xRotation() const { return d_ptr->decomposedTransform()->xRotation; } +/*! + \since 4.6 + + Sets the rotation around the X axis to \a angle degrees. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, it will be overwritten. + + \sa xRotation(), {Transformations} +*/ void QGraphicsItem::setXRotation(qreal angle) { if (!d_ptr->dirtyTransform) { @@ -2647,24 +2655,32 @@ void QGraphicsItem::setXRotation(qreal angle) } /*! - \property QGraphicsItem::yRotation - \since 4.6 - This property holds the rotation angle in degrees around the Y axis + Returns the rotation around the Y axis. The default is 0 \warning setting this property is conflicting with calling setTransform. If a transform has been set, this function return the default value. - \sa {Transformations} + \sa setYRotation(), {Transformations} */ qreal QGraphicsItem::yRotation() const { return d_ptr->decomposedTransform()->yRotation; } +/*! + \since 4.6 + + Sets the rotation around the Y axis to \a angle degrees. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, it will be overwritten. + + \sa yRotation(), {Transformations} +*/ void QGraphicsItem::setYRotation(qreal angle) { if (!d_ptr->dirtyTransform) { @@ -2680,24 +2696,32 @@ void QGraphicsItem::setYRotation(qreal angle) } /*! - \property QGraphicsItem::zRotation - \since 4.6 - This property holds the rotation angle in degrees around the Z axis + Returns the rotation around the Z axis. The default is 0 \warning setting this property is conflicting with calling setTransform. If a transform has been set, this function return the default value. - \sa {Transformations} + \sa setZRotation(), {Transformations} */ qreal QGraphicsItem::zRotation() const { return d_ptr->decomposedTransform()->zRotation; } +/*! + \since 4.6 + + Sets the rotation around the Z axis to \a angle degrees. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, it will be overwritten. + + \sa zRotation(), {Transformations} +*/ void QGraphicsItem::setZRotation(qreal angle) { if (!d_ptr->dirtyTransform) { @@ -2712,6 +2736,14 @@ void QGraphicsItem::setZRotation(qreal angle) d_ptr->hasTransform = 1; } +/*! + \since 4.6 + + This convenience function set the rotation angles around the 3 axes + to \a x, \a y and \a z. + + \sa setXRotation(), setYRotation(), setZRotation() +*/ void QGraphicsItem::setRotation(qreal x, qreal y, qreal z) { setXRotation(x); @@ -2720,24 +2752,32 @@ void QGraphicsItem::setRotation(qreal x, qreal y, qreal z) } /*! - \property QGraphicsItem::xScale - \since 4.6 - This property holds the scale factor on the X axis. + Returns the scale factor on the X axis. The default is 1 \warning setting this property is conflicting with calling setTransform. If a transform has been set, this function return the default value. - \sa {Transformations} + \sa setXScale(), {Transformations} */ qreal QGraphicsItem::xScale() const { return d_ptr->decomposedTransform()->xScale; } +/*! + \since 4.6 + + Sets the scale factor on the X axis to \a factor. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, it will be overwritten. + + \sa xScale(), {Transformations} +*/ void QGraphicsItem::setXScale(qreal factor) { if (!d_ptr->dirtyTransform) { @@ -2753,24 +2793,32 @@ void QGraphicsItem::setXScale(qreal factor) } /*! - \property QGraphicsItem::yScale - \since 4.6 - This property holds the scale factor on the Y axis. + Returns the scale factor on the Y axis. The default is 1 \warning setting this property is conflicting with calling setTransform. If a transform has been set, this function return the default value. - \sa {Transformations} + \sa setYScale(), {Transformations} */ qreal QGraphicsItem::yScale() const { return d_ptr->decomposedTransform()->yScale; } +/*! + \since 4.6 + + Sets the scale factor on the Y axis to \a factor. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, it will be overwritten. + + \sa yScale(), {Transformations} +*/ void QGraphicsItem::setYScale(qreal factor) { if (!d_ptr->dirtyTransform) { @@ -2785,6 +2833,13 @@ void QGraphicsItem::setYScale(qreal factor) d_ptr->hasTransform = 1; } +/*! + \since 4.6 + + This convenience function set the scaling factors on X and Y axis to \a sx and \a sy. + + \sa setXScale(), setYScale() +*/ void QGraphicsItem::setScale(qreal sx, qreal sy) { setXScale(sx); @@ -2792,24 +2847,32 @@ void QGraphicsItem::setScale(qreal sx, qreal sy) } /*! - \property QGraphicsItem::horizontalShear - \since 4.6 - This property holds the horizontal shear. + Returns the horizontal shear. - The default is 0. + The default is 0 \warning setting this property is conflicting with calling setTransform. If a transform has been set, this function return the default value. - \sa {Transformations} + \sa setHorizontalShear(), {Transformations} */ qreal QGraphicsItem::horizontalShear() const { return d_ptr->decomposedTransform()->horizontalShear; } +/*! + \since 4.6 + + Sets the horizontal shear to \a shear. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, it will be overwritten. + + \sa horizontalShear(), {Transformations} +*/ void QGraphicsItem::setHorizontalShear(qreal shear) { if (!d_ptr->dirtyTransform) { @@ -2825,24 +2888,32 @@ void QGraphicsItem::setHorizontalShear(qreal shear) } /*! - \property QGraphicsItem::verticalShear - \since 4.6 - This property holds the vertical shear. + Returns the vertical shear. - The default is 0. + The default is 0 \warning setting this property is conflicting with calling setTransform. If a transform has been set, this function return the default value. - \sa {Transformations} + \sa setHorizontalShear(), {Transformations} */ qreal QGraphicsItem::verticalShear() const { return d_ptr->decomposedTransform()->verticalShear; } +/*! + \since 4.6 + + Sets the vertical shear to \a shear. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, it will be overwritten. + + \sa verticalShear(), {Transformations} +*/ void QGraphicsItem::setVerticalShear(qreal shear) { if (!d_ptr->dirtyTransform) { @@ -2857,6 +2928,13 @@ void QGraphicsItem::setVerticalShear(qreal shear) d_ptr->hasTransform = 1; } +/*! + \since 4.6 + + This convenience function sets the horizontal shear to \a sh and the vertical shear to \a sv. + + \sa setHorizontalShear(), setVerticalShear() +*/ void QGraphicsItem::setShear(qreal sh, qreal sv) { setHorizontalShear(sh); @@ -2864,19 +2942,16 @@ void QGraphicsItem::setShear(qreal sh, qreal sv) } /*! - \property QGraphicsItem::transformOrigin - \since 4.6 - This property holds the transformation origin for the transformation properties. - This does not apply to the transformation set by setTransform. + Returns the transformation origin for the transformation properties. The default is QPointF(0,0). \warning setting this property is conflicting with calling setTransform. If a transform has been set, this function return the default value. - \sa {Transformations} + \sa setTransformOrigin(), {Transformations} */ QPointF QGraphicsItem::transformOrigin() const { @@ -2884,6 +2959,29 @@ QPointF QGraphicsItem::transformOrigin() const return QPointF(decomposed->xOrigin, decomposed->yOrigin); } +/*! + \fn inline void setTransformOrigin(qreal x, qreal y) + + \since 4.6 + + This is an overloaded member function, provided for convenience. + Sets the transformation origin for the transformation + properties to the point(\a x, \a y). + + \sa setTransformOrigin(), {Transformations} +*/ + +/*! + \since 4.6 + + Sets the transformation origin for the transformation properties to \a origin. + This does not apply to the transformation set by setTransform. + + \warning setting this property is conflicting with calling setTransform. + If a transform has been set, it will be overwritten. + + \sa transformOrigin(), {Transformations} +*/ void QGraphicsItem::setTransformOrigin(const QPointF &origin) { if (!d_ptr->dirtyTransform) { diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index a2e55e1..341f9a2 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -200,7 +200,55 @@ QT_BEGIN_NAMESPACE /*! \property QGraphicsWidget::pos \brief the position of the widget -*/ +*/ + +/*! + \property QGraphicsWidget::xRotation + \since 4.6 + \brief the rotation angle in degrees around the X axis +*/ + +/*! + \property QGraphicsWidget::yRotation + \since 4.6 + \brief the rotation angle in degrees around the Y axis +*/ + +/*! + \property QGraphicsWidget::zRotation + \since 4.6 + \brief the rotation angle in degrees around the Z axis +*/ + +/*! + \property QGraphicsWidget::xScale + \since 4.6 + \brief the scale factor on the X axis. +*/ + +/*! + \property QGraphicsWidget::yScale + \since 4.6 + \brief the scale factor on the Y axis. +*/ + +/*! + \property QGraphicsWidget::horizontalShear + \since 4.6 + \brief the horizontal shear. +*/ + +/*! + \property QGraphicsWidget::verticalShear + \since 4.6 + \brief the vertical shear. +*/ + +/*! + \property QGraphicsWidget::transformOrigin + \since 4.6 + \brief the transformation origin for the transformation properties. +*/ /*! Constructs a QGraphicsWidget instance. The optional \a parent argument is -- cgit v0.12 From 8bf5a6986db852525582713cc2f2a760df4fdc60 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 26 May 2009 16:50:48 +0200 Subject: QFileDialog selection bug when calling it multiple times. The problem was that we don't clear the selection model if the previous selection was valid. Task-number:251341 Reviewed-by:jasplin --- src/gui/dialogs/qfiledialog.cpp | 11 +++++----- tests/auto/qfiledialog/tst_qfiledialog.cpp | 33 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index eeb2743..d42775a 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -776,6 +776,7 @@ void QFileDialog::selectFile(const QString &filename) } QModelIndex index = d->model->index(filename); + QString file; if (!index.isValid()) { // save as dialog where we want to input a default value QString text = filename; @@ -790,13 +791,13 @@ void QFileDialog::selectFile(const QString &filename) ) text = text.remove(0,1); } - if (!isVisible() || !d->lineEdit()->hasFocus()) - d->lineEdit()->setText(text); + file = text; } else { - d->qFileDialogUi->listView->selectionModel()->clear(); - if (!isVisible() || !d->lineEdit()->hasFocus()) - d->lineEdit()->setText(index.data().toString()); + file = index.data().toString(); } + d->qFileDialogUi->listView->selectionModel()->clear(); + if (!isVisible() || !d->lineEdit()->hasFocus()) + d->lineEdit()->setText(file); } /** diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index 689f73d..16c84d8 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -159,6 +159,7 @@ private slots: void task218353_relativePaths(); void task251321_sideBarHiddenEntries(); void task251341_sideBarRemoveEntries(); + void task254490_selectFileMultipleTimes(); private: QByteArray userSettings; @@ -1981,5 +1982,37 @@ void tst_QFiledialog::task251341_sideBarRemoveEntries() current.rmdir("testDir"); } +void tst_QFiledialog::task254490_selectFileMultipleTimes() +{ + QString tempPath = QDir::tempPath(); + QTemporaryFile *t; + t = new QTemporaryFile; + t->open(); + QNonNativeFileDialog fd(0, "TestFileDialog"); + + fd.setDirectory(tempPath); + fd.setViewMode(QFileDialog::List); + fd.setAcceptMode(QFileDialog::AcceptSave); + fd.setFileMode(QFileDialog::AnyFile); + + //This should select the file in the QFileDialog + fd.selectFile(t->fileName()); + + //This should clear the selection and write it into the filename line edit + fd.selectFile("new_file.txt"); + + fd.show(); + QTest::qWait(250); + + QLineEdit *lineEdit = qFindChild(&fd, "fileNameEdit"); + QVERIFY(lineEdit); + QCOMPARE(lineEdit->text(),QLatin1String("new_file.txt")); + QListView *list = qFindChild(&fd, "listView"); + QVERIFY(list); + QCOMPARE(list->selectionModel()->selectedRows(0).count(), 0); + + t->deleteLater(); +} + QTEST_MAIN(tst_QFiledialog) #include "tst_qfiledialog.moc" -- cgit v0.12 From 639557d7e2df5fc1b3ffdc76188b3084c13a8fc3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 26 May 2009 17:23:22 +0200 Subject: Fixed crash when encountering invalid forms. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Crash when replacing the QDockWidget contents widget by a widget using a container extension. Task-number: 254553 --- tools/designer/src/components/formeditor/formwindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/designer/src/components/formeditor/formwindow.cpp b/tools/designer/src/components/formeditor/formwindow.cpp index 07d785a..66bab9b 100644 --- a/tools/designer/src/components/formeditor/formwindow.cpp +++ b/tools/designer/src/components/formeditor/formwindow.cpp @@ -2136,7 +2136,10 @@ void FormWindow::layoutContainer(QWidget *w, int type) bool FormWindow::hasInsertedChildren(QWidget *widget) const // ### move { if (QDesignerContainerExtension *container = qt_extension(core()->extensionManager(), widget)) { - widget = container->widget(container->currentIndex()); + const int index = container->currentIndex(); + if (index < 0) + return false; + widget = container->widget(index); } const QWidgetList l = widgets(widget); -- cgit v0.12 From cfe54548131d78db9d58366e35e9b29e5d3ba238 Mon Sep 17 00:00:00 2001 From: Thomas Sondergaard Date: Fri, 22 May 2009 20:26:46 +0200 Subject: Updated danish translations. Added them to relevant project files. --- tools/assistant/translations/qt_help.pro | 3 +- tools/assistant/translations/translations.pro | 3 +- translations/assistant_da.ts | 606 ++++---- translations/qt_da.ts | 1978 +++++++++++++++++++++---- translations/qt_help_da.ts | 177 ++- translations/translations.pri | 2 +- 6 files changed, 2132 insertions(+), 637 deletions(-) diff --git a/tools/assistant/translations/qt_help.pro b/tools/assistant/translations/qt_help.pro index efad6bf..e6208a6 100644 --- a/tools/assistant/translations/qt_help.pro +++ b/tools/assistant/translations/qt_help.pro @@ -44,5 +44,6 @@ TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/qt_help_de.ts \ $$[QT_INSTALL_TRANSLATIONS]/qt_help_pl.ts \ $$[QT_INSTALL_TRANSLATIONS]/qt_help_untranslated.ts \ $$[QT_INSTALL_TRANSLATIONS]/qt_help_zh_CN.ts \ - $$[QT_INSTALL_TRANSLATIONS]/qt_help_zh_TW.ts + $$[QT_INSTALL_TRANSLATIONS]/qt_help_zh_TW.ts \ + $$[QT_INSTALL_TRANSLATIONS]/qt_help_da.ts error("This is a dummy profile to be used for translations ONLY.") diff --git a/tools/assistant/translations/translations.pro b/tools/assistant/translations/translations.pro index 58de554..8572123 100644 --- a/tools/assistant/translations/translations.pro +++ b/tools/assistant/translations/translations.pro @@ -45,4 +45,5 @@ TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/assistant_de.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_pl.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_untranslated.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_zh_CN.ts \ - $$[QT_INSTALL_TRANSLATIONS]/assistant_zh_TW.ts + $$[QT_INSTALL_TRANSLATIONS]/assistant_zh_TW.ts \ + $$[QT_INSTALL_TRANSLATIONS]/assistant_da.ts diff --git a/translations/assistant_da.ts b/translations/assistant_da.ts index d039248..8d134fc 100644 --- a/translations/assistant_da.ts +++ b/translations/assistant_da.ts @@ -1,58 +1,77 @@ - AboutDialog - + &Close &Luk + AboutLabel + + + Warning + Advarsel + + + + Unable to launch external application. + + Kunne ikke starte ekstern applikation. + + + + + OK + + + + BookmarkDialog - - - - - + + + + + Bookmarks Favoritter - + Add Bookmark Føj til Favoritter - + Bookmark: Favorit: - + Add in Folder: Føj til mappen: - + + - + New Folder Ny mappe - + Delete Folder Slet mappe - + Rename Folder Omdøb mappe @@ -60,75 +79,79 @@ BookmarkManager - + Bookmarks Favoritter - + Remove Fjern + You are going to delete a Folder, this will also<br>remove it's content. Are you sure to continue? - Ved at slette denne mappe fjernes hele mappens<br>indhold. Ă˜nsker du alligevel at slette? + Ved at slette denne mappe fjernes hele mappens<br>indhold. Ă˜nsker du alligevel at slette? - - + + New Folder Ny mappe - You are about to delete a folder which means that its content<br>will also be removed. Do you want to continue? - Ved at slette denne mappe fjernes hele mappens indhold.<br>Ă˜nsker du alligevel at slette? + Ved at slette denne mappe fjernes hele mappens indhold.<br>Ă˜nsker du alligevel at slette? BookmarkWidget - + + Filter: + Filter: + + + Remove Fjern - + Delete Folder Slet mappe - + Rename Folder Omdøb mappe - + Show Bookmark Vis favorit - + Show Bookmark in New Tab Vis favorit pĂ¥ ny fane - + Delete Bookmark Slet favorit - + Rename Bookmark Omdøb favorit - Search for: - Søg efter: + Søg efter: - + Add Tilføj @@ -136,48 +159,48 @@ CentralWidget - + Add new page Tilføj ny side - + Close current page Luk nuværende side - + Print Document Udskriv dokument - - + + unknown ukendt - + Add New Page Tilføj ny side - + Close This Page Luk denne side - + Close Other Pages Luk de andre sider - + Add Bookmark for this Page... Føj denne side til Favoritter... - + Search Søg @@ -185,12 +208,12 @@ ContentWindow - + Open Link Ă…bn link - + Open Link in New Tab Ă…bn link pĂ¥ ny fane @@ -198,69 +221,77 @@ FilterNameDialogClass - FilterNameDialog - FilterNavnDialog + FilterNavnDialog - + Filter Name: Filternavn: + + + Add Filter Name + Tilføj filternavn + FindWidget - + + <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped + <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Søgning gentaget fra start + + + Previous Forrige - + Next Næste - + Case Sensitive Der skelnes mellem store og smĂ¥ bogstaver - + Whole words Hele ord - <img src="%1">&nbsp;Search wrapped <img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped - <img src="%1">&nbsp;Søgning startet forfra + <img src="%1">&nbsp;Søgning startet forfra FontPanel - + Font Skrifttype - + &Writing system &Skrivesystem - + &Family &Familie - + &Style &Stil - + &Point size &Punktstørrelse @@ -268,42 +299,41 @@ HelpViewer - + Help Hjælp - + OK - + <title>Error 404...</title><div align="center"><br><br><h1>The page could not be found</h1><br><h3>'%1'</h3></div> <title>Fejl 404...</title><div align="center"><br><br><h1>Siden blev ikke fundet</h1><br><h3>'%1'</h3></div> - + Copy &Link Location KopiĂ©r &linkets placering - + Open Link in New Tab Ctrl+LMB Ă…bn link pĂ¥ ny fane Ctrl+LMB - + Open Link in New Tab Ă…bn link pĂ¥ ny fane - <b>Page not found:<p>%1.</p></b> - <b>Kunne ikke finde siden:<p>%1.</p></b> + <b>Kunne ikke finde siden:<p>%1.</p></b> - + Unable to launch external application. Kunne ikke starte ekstern applikation. @@ -313,17 +343,17 @@ IndexWindow - + &Look for: &Søg efter: - + Open Link Ă…bn link - + Open Link in New Tab Ă…bn link pĂ¥ ny fane @@ -331,99 +361,99 @@ InstallDialog - - + + Install Documentation InstallĂ©r dokumentation - + Downloading documentation info... Downloader dokumentationsinformation... - + Download canceled. Download blev annulleret. - - - + + + Done. Færdig. - + The file %1 already exists. Do you want to overwrite it? Filen %1 findes allerede. Ă˜nsker du at overskrive? - + Unable to save the file %1: %2. Kunne ikke gemme filen %1: %2. - + Downloading %1... Downloader %1... - - - + + + Download failed: %1. Download mislykkedes: %1. - + Documentation info file is corrupt! Dokumentationsinformationsfilen er ødelagt! - + Download failed: Downloaded file is corrupted. Download mislykkedes: Den downloadede fil er ødelagt. - + Installing documentation %1... Installerer dokumentation %1... - + Error while installing documentation: %1 Der opstod fejl under installation af dokumentation: %1 - + Available Documentation: Tilgængeligt dokumentation: - + Install InstallĂ©r - + Cancel Annuller - + Close Luk - + Installation Path: Installationssti: - + ... @@ -431,60 +461,62 @@ MainWindow - - + + Index Indeks - - + + Contents Indhold - - + + Bookmarks Favoritter - - + Search Søg - - - + + + Qt Assistant - - + + Unfiltered Ufiltreret + Page Set&up... - Side&opsætning... + Side&opsætning... + Print Preview... - Vis udskrift... + Vis udskrift... + &Print... - &Udskriv... + &Udskriv... CTRL+P Ctrl+U - + New &Tab &Ny Fane @@ -493,7 +525,7 @@ Ctrl+N - + &Close Tab &Luk fane @@ -502,340 +534,326 @@ Ctrl+L - + &Quit &Afslut + CTRL+Q - Ctrl+A + Ctrl+A + &Copy selected Text - &KopiĂ©r markeret tekst + &KopiĂ©r markeret tekst Ctrl+C Ctrl+K - + &Find in Text... &Find i tekst... - - Ctrl+F - - - - + Find &Next Find N&æste - - F3 - - - - + Find &Previous Find fo&rrige - - Shift+F3 - - - - + Preferences... Indstillinger... - + Zoom &in Zoom &ind - - Ctrl++ - - - - + Zoom &out Zoom u&d - - Ctrl+- - - - - + Normal &Size Normal &størrelse - + Ctrl+0 - + + ALT+C + + + + + ALT+I + + + + + ALT+S + + + + &Home &Hjem - + Ctrl+Home - + &Back &Tilbage - + &Forward Fr&em + Sync with Table of Contents - SynkronisĂ©r med Indholdsfortegnelse + SynkronisĂ©r med Indholdsfortegnelse - + Next Page Næste side - + Ctrl+Alt+Right Ctrl+Alt+Højre - + Previous Page Forrige side - + Ctrl+Alt+Left Ctrl+Alt+Venstre - + Add Bookmark... Føj til Favoritter... - + About... Om... - + Navigation Toolbar Navigationsværktøjslinie - + Toolbars Værktøjslinier - + Filter Toolbar Filtrer værktøjslinie - + Filtered by: Filtreret efter: - + Address Toolbar Adresseværktøjslinie - + Address: Adresse: - + Could not find the associated content item. Det tilhørende indholdselement kunne ikke findes. - - Open Source Edition - - - - This version of Qt Assistant is part of the Qt Open Source Edition, for use in the development of Open Source applications. Qt is a comprehensive C++ framework for cross-platform application development. - Denne version af Qt Assistant er en del af Qt Open Source Edition til brug med henblik pĂ¥ udvikling af Open Source-applikationer. Qt er et omfattende C++ framework for cross-platform applikationsudvikling. + Denne version af Qt Assistant er en del af Qt Open Source Edition til brug med henblik pĂ¥ udvikling af Open Source-applikationer. Qt er et omfattende C++ framework for cross-platform applikationsudvikling. - This program is licensed to you under the terms of the Qt Commercial License Agreement. For details, see the file LICENSE that came with this software distribution. - Dette program er omfattet af Qt Commercial License Agreement. Se filen LICENCE, der var vedlagt denne software-distribution, for yderligere detaljer. + Dette program er omfattet af Qt Commercial License Agreement. Se filen LICENCE, der var vedlagt denne software-distribution, for yderligere detaljer. - + About %1 Om %1 - + Updating search index Opdaterer søgeindeks - + Looking for Qt Documentation... Søger efter Qt-dokumentation... - + &Window &Vindue - + Minimize MinimĂ©r - + Ctrl+M Ctrl+M - + Zoom - + &File &Filer - + &Edit &RedigĂ©r - + &View &Vis - + &Go &GĂ¥ til - + &Bookmarks F&avoritter - + &Help &Hjælp - - You need a commercial Qt license for development of proprietary (closed source) applications. Please see <a href="http://trolltech.com/company/about/businessmodel">http://trolltech.com/company/about/businessmodel</a> for an overview of Qt licensing. - - - + ALT+O - Alt+F + Alt+F + CTRL+D - Ctrl+Ă˜ + Ctrl+Ă˜ Ctrl+P Ctrl+U - Ctrl+T - Ctrl+N + Ctrl+N - Ctrl+W - Ctrl+L + Ctrl+L - Ctrl+Q - Ctrl+A + Ctrl+A - Alt+C - Alt+L - - - - Alt+I - + Alt+L - Alt+O - Alt+F - - - - Alt+S - + Alt+F - Ctrl+D - Ctrl+Ă˜ + Ctrl+Ă˜ PreferencesDialog - - - + + Add Documentation Tilføj dokumentation - + Qt Compressed Help Files (*.qch) Qt komprimeret hjælpefil (*.qch) - + The specified file is not a valid Qt Help File! Den anførte fil er ikke en gyldig Qt hjælpefil! - + The namespace %1 is already registered! Navnerummet %1 er allerede registreret! - + + Remove Documentation + Fjern dokumentation + + + + Some documents currently opened in Assistant reference the documentation you are attempting to remove. Removing the documentation will close those documents. + Nogle dokumenter der pt er Ă¥bne i Assistant refererer til den dokumentation du prøver at fjerne. Fjernelse af dokumentation vil resultere i lukning af disse dokumenter. + + + + Cancel + Annuller + + + + OK + + + + Use custom settings Benyt brugerdefineret opsætning @@ -843,158 +861,170 @@ PreferencesDialogClass - + Preferences Indstillinger - + Fonts Skrifttyper - + Font settings: Indstillinger for skrifttype: - + Browser - + Application Applikation - + Filters Filtre - + Filter: Filter: - + Attributes: Attributter: - + 1 - + Add Tilføj - - + Remove Fjern - + Documentation Dokumentation - + Registered Documentation: Registreret dokumentation: - + Add... Tilføj... - Network - Netværk + Netværk - Use Http Proxy - Benyt Http Proxy + Benyt Http Proxy - - Http Proxy: - + + Options + Indstillinger - - Port: - + + Homepage + Hjemmeside + + + + Current Page + Nuværende side + + + + Restore to default + Nulstil til default QObject - + The specified collection file does not exist! Den angivne hjælpesamling findes ikke! - + Missing collection file! Hjælpesamling mangler! - + Invalid URL! Ugyldig URL! - + Missing URL! URL mangler! - - - + + + Unknown widget: %1 Ukendt widget: %1 - - - + + + Missing widget! Widget mangler! - - + + The specified Qt help file does not exist! Den angivne Qt-hjælpefil findes ikke! - - + + Missing help file! Hjælpefilen mangler! - + + Missing filter argument! + Manglende filterargument! + + + Unknown option: %1 Ukendt parameter: %1 - - + + Qt Assistant - + Could not register documentation file %1 @@ -1007,12 +1037,12 @@ Reason: %2 - + Documentation successfully registered. Dokumentationen blev registreret. - + Could not unregister documentation file %1 @@ -1025,18 +1055,23 @@ Reason: %2 - + Documentation successfully unregistered. Dokumentationen blev afregistreret. - + + Cannot load sqlite database driver! + Kan ikke indlæse sqlite database-driver! + + + The specified collection file could not be read! Den angivne hjælpesamling kunne ikke læses! - - + + Bookmark Favorit @@ -1044,11 +1079,10 @@ Reason: QtDocInstaller - The file %1 could not be registered successfully! Reason: %2 - Filen %1 kunne ikke registreres! + Filen %1 kunne ikke registreres! Ă…rsag: %2 @@ -1056,12 +1090,12 @@ Reason: %2 RemoteControl - + Debugging Remote Control - + Received Command: %1 %2 Modtaget kommando: %1 %2 @@ -1069,56 +1103,54 @@ Reason: %2 SearchWidget - + &Copy &KopiĂ©r - + Copy &Link Location KopiĂ©r &linkets placering - - + Open Link in New Tab Ă…bn link pĂ¥ ny fane - + Select All MarkĂ©r alt - Open Link - Ă…bn link + Ă…bn link TopicChooser - + Choose a topic for <b>%1</b>: Vælg et emne for <b>%1</b>: - + Choose Topic Vælg emne - + &Topics &Emner - + &Display &Vis - + &Close &Luk diff --git a/translations/qt_da.ts b/translations/qt_da.ts index 9350687..105b572 100644 --- a/translations/qt_da.ts +++ b/translations/qt_da.ts @@ -4,15 +4,17 @@ AudioOutput - + <html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html> <html>Audio-playback-enheden<b>%1</b> virker ikke.<br/>Falder tilbage til <b>%2</b>.</html> + <html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html> - <html>Skifter til audio-playback-enheden, <b>%1</b><br/>der lige er blevet tilgængeligt og har en højere præference.</html> + <html>Skifter til audio-playback-enheden, <b>%1</b><br/>der lige er blevet tilgængelig og har en højere præference.</html> + Revert back to device '%1' GĂ¥ tilbage til enheden '%1' @@ -20,7 +22,7 @@ CloseButton - + Close Tab Luk fane @@ -28,27 +30,32 @@ Phonon:: - + Notifications Meddelelser + Music Musik + Video + Communication Kommunikation + Games Spil + Accessibility Tilgængelighed @@ -56,13 +63,14 @@ Phonon::Gstreamer::Backend - + Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. Some video features have been disabled. Advarsel: Det ser ikke ud til, at gstreamer0.10-plugins-good pakken er installeret. Nogle videofunktioner er deaktiveret. + Warning: You do not seem to have the base GStreamer plugins installed. All audio and video support has been disabled Advarsel: Det ser ikke ud til, at base GStreamer plugins er installeret. @@ -72,7 +80,7 @@ Phonon::Gstreamer::MediaObject - + Cannot start playback. Check your Gstreamer installation and make sure you @@ -83,26 +91,39 @@ Tjek Gstreamer-installationen og kontrollĂ©r, at libgstreamer-plugins-base er installeret. + A required codec is missing. You need to install the following codec(s) to play this content: %0 Der mangler et codec. Følgende codecs skal installeres for at afspille dette indhold: %0 + + + + + + + + Could not open media source. Kunne ikke Ă¥bne mediekilden. + Invalid source type. Ugyldig kilde. + Could not locate media source. Kunne ikke lokalisere mediekilden. + Could not open audio device. The device is already in use. Kunne ikke Ă¥bne lydenheden. Enheden er allerede i brug. + Could not decode media source. Kunne ikke afkode mediekilden. @@ -110,10 +131,15 @@ libgstreamer-plugins-base er installeret. Phonon::VolumeSlider + + Volume: %1% + + + Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1% Anvend denne skyder til at indstille lydstyrken. Længst til venstre er 0% og længst til højre er %1% @@ -121,11 +147,12 @@ libgstreamer-plugins-base er installeret. Q3Accel - + %1, %2 not defined %1, %2 ikke definerede + Ambiguous %1 not handled Tvetydig %1 ikke behandlet @@ -133,23 +160,27 @@ libgstreamer-plugins-base er installeret. Q3DataTable - + True Sandt + False Falsk + Insert Indsæt + Update Opdater + Delete Slet @@ -157,242 +188,313 @@ libgstreamer-plugins-base er installeret. Q3FileDialog - + Copy or Move a File KopiĂ©r eller flyt en fil + Read: %1 Læs: %1 + + Write: %1 Skriv: %1 + + Cancel Annuller - + + + + All Files (*) Alle filer (*) + Name Navn + Size Størrelse + Type + Date Dato + Attributes Attributter + + &OK &OK + Look &in: Kig &i: + + + File &name: Fil&navn: + File &type: Fil&type: + Back Tilbage + One directory up En mappe op + Create New Folder Opret ny folder + List View Listevisning + Detail View Detaljevisning + Preview File Info Vis filinformation + Preview File Contents Vis filindhold + Read-write Læs-skriv + Read-only Skrivebeskyttet + Write-only Write-only + Inaccessible Utilgængelig + Symlink to File Symlink til Fil + Symlink to Directory Symlink til katalog + Symlink to Special Symlink til Speciel + File Fil + Dir Katalog + Special Speciel - + + + Open Ă…bn - + + Save As Gem som + + + &Open &Ă…bn + + &Save &Gem + &Rename &Omdøb + &Delete &Slet + R&eload Gen&indlæs + Sort by &Name SortĂ©r efter n&avn + Sort by &Size SortĂ©r efter s&tørrelse + Sort by &Date SortĂ©r efter &dato + &Unsorted &Usorteret + Sort SortĂ©r + Show &hidden files Vis s&kjulte filer + the file filen + the directory kataloget + the symlink symlinket + Delete %1 Slet %1 + <qt>Are you sure you wish to delete %1 "%2"?</qt> <qt>Er du sikker pĂ¥, at du vil slette %1 "%2"?</qt> + &Yes &Ja + &No &Nej + New Folder 1 Ny folder 1 + New Folder Ny folder + New Folder %1 Ny folder %1 + Find Directory Find katalog + + Directories Kataloger + Directory: Katalog: + + Error Fejl + %1 File not found. Check path and filename. @@ -401,14 +503,17 @@ Filen blev ikke fundet. KontrollĂ©r sti og filnavn. + All Files (*.*) Alle filer (*.*) + Open Ă…bn + Select a Directory Vælg et katalog @@ -416,24 +521,29 @@ KontrollĂ©r sti og filnavn. Q3LocalFs + + Could not read directory %1 Kunne ikke læse katalog %1 + Could not create directory %1 Kunne ikke oprette katalog %1 + Could not remove file or directory %1 Kunne ikke fjerne fil eller katalog %1 + Could not rename %1 to @@ -444,12 +554,14 @@ to %2 + Could not open %1 Kunne ikke Ă¥bne %1 + Could not write %1 Kunne ikke skrive @@ -459,11 +571,12 @@ to Q3MainWindow - + Line up Linie op + Customize... Tilpas... @@ -471,7 +584,7 @@ to Q3NetworkProtocol - + Operation stopped by the user Brugeren stoppede handlingen @@ -479,6 +592,8 @@ to Q3ProgressDialog + + Cancel Annuller @@ -486,22 +601,28 @@ to Q3TabDialog + + OK + Apply Udfør + Help Hjælp + Defaults Standarder + Cancel Annuller @@ -509,31 +630,38 @@ to Q3TextEdit - + &Undo &Fortryd + &Redo &Gendan + Cu&t &Klip + &Copy K&opiĂ©r + &Paste &Sæt ind + Clear Ryd + + Select All MarkĂ©r alt @@ -541,55 +669,67 @@ to Q3TitleBar - + System + Restore up Gendan op + Minimize Minimer + Restore down Gendan ned + Maximize MaksimĂ©r + Close Luk + Contains commands to manipulate the window Indeholder kommandoer til indstilling af vinduet + Puts a minimized back to normal Sætter et minimeret vindue til normal størrelse + Moves the window out of the way Flytter vinduet væk + Puts a maximized window back to normal Sætter et maksimeret vindue til normal størrelse + Makes the window full screen Gør vinduet til fuld skærm + Closes the window Lukker vinduet + Displays the name of the window and contains controls to manipulate it Viser vinduets navn og indeholder kontroller til indstilling af vinduet @@ -597,7 +737,7 @@ to Q3ToolBar - + More... Mere... @@ -605,38 +745,51 @@ to Q3UrlOperator + + + The protocol `%1' is not supported Protokollen '%1' understøttes ikke + The protocol `%1' does not support listing directories Protokollen '%1' understøtter ikke opremsning af kataloger + The protocol `%1' does not support creating new directories Protokollen '%1' understøtter ikke oprettelse af nye kataloger + The protocol `%1' does not support removing files or directories Protokollen '%1' understøtter ikke, at filer eller kataloger fjernes + The protocol `%1' does not support renaming files or directories Protokollen '%1' understøtter ikke, at filer eller kataloger omdøbes + The protocol `%1' does not support getting files Protokollen '%1' understøtter ikke hentning af filer + The protocol `%1' does not support putting files Protokollen '%1' understøtter ikke upload af filer + + The protocol `%1' does not support copying or moving files or directories Protokollen '%1' understøtter ikke kopiering eller flytning af filer eller kataloger + + (unknown) (ukendt) @@ -644,23 +797,27 @@ to Q3Wizard - + &Cancel &Annuller + < &Back < &Tilbage + &Next > &Næste > + &Finish &Udfør + &Help &Hjælp @@ -668,31 +825,44 @@ to QAbstractSocket + + + + Host not found Host blev ikke fundet - + + + Connection refused Forbindelse afvist + Connection timed out Forbindelsen timed out + + + Operation on socket is not supported Socket-operation ikke understøttet + Socket operation timed out Socket-operation timed out + Socket is not connected Socket ikke forbundet + Network unreachable Netværket er ikke tilgængeligt @@ -700,15 +870,17 @@ to QAbstractSpinBox - + &Step up &Trin op + Step &down Trin &ned + &Select All &Vælg alle @@ -716,27 +888,28 @@ to QApplication - + Activate AktivĂ©r - + Executable '%1' requires Qt %2, found Qt %3. Eksekverbar '%1' kræver Qt %2, ikke fundet Qt %3. + Incompatible Qt Library Error Inkompatibel Qt Library fejl - + QT_LAYOUT_DIRECTION Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. - + Activates the program's main window Aktiverer programmets hovedvindue @@ -744,18 +917,22 @@ to QAxSelect + Select ActiveX Control Vælg ActiveX-kontrol + OK + &Cancel &Annuller + COM &Object: COM &Objekt: @@ -763,15 +940,17 @@ to QCheckBox - + Uncheck Fjern markering + Check Kryds af + Toggle SlĂ¥ til/fra @@ -779,47 +958,57 @@ to QColorDialog - + Hu&e: Ton&e: + &Sat: &Mæt: + &Val: &Vær: + &Red: &Rød: + &Green: &Grøn: + Bl&ue: Bl&Ă¥: + A&lpha channel: Al&fa-kanal: + Select Color Vælg farve + &Basic colors &Basisfarver + &Custom colors &Egne farver + &Add to Custom Colors &Føj til egne farver @@ -827,20 +1016,23 @@ to QComboBox + + Open Ă…bn - + False Falsk + True Sandt - + Close Luk @@ -848,17 +1040,19 @@ to QCoreApplication - + %1: key is empty QSystemSemaphore %1: nøgle er tom + %1: unable to make key QSystemSemaphore %1: kunne ikke lave nøgle + %1: ftok failed QSystemSemaphore %1: ftok mislykkedes @@ -867,19 +1061,22 @@ to QDB2Driver - + Unable to connect Kunne ikke skabe forbindelse + Unable to commit transaction Kunne ikke gennemføre transaktion + Unable to rollback transaction Kunne ikke tilbagetrække transaktion + Unable to set autocommit Kunne ikke aktivere autocommit @@ -887,26 +1084,33 @@ to QDB2Result + + Unable to execute statement Kunne ikke udføre statement + Unable to prepare statement Kunne ikke forberede udsagn + Unable to bind variable Kunne ikke binde variabel + Unable to fetch record %1 Kunne ikke hente post %1 + Unable to fetch next Kunne ikke hente næste + Unable to fetch first Kunne ikke hente første @@ -914,19 +1118,22 @@ to QDateTimeEdit - + AM + am + PM + pm @@ -934,15 +1141,17 @@ to QDial - + QDial + SpeedoMeter Speedometer + SliderHandle @@ -950,11 +1159,12 @@ to QDialog - + What's This? Hvad er dette? + Done Udført @@ -962,100 +1172,124 @@ to QDialogButtonBox - + + + OK - + &OK + &Save &Gem + Save Gem + Open Ă…bn + &Cancel &Annuller + Cancel Annuller + &Close &Luk + Close Luk + Apply Udfør + Reset Nulstil + Help Hjælp + Don't Save Gem ikke + Discard KassĂ©r + &Yes &Ja + Yes to &All Ja til &alle + &No &Nej + N&o to All Ne&j til alle + Save All Gem alle + Abort Afbryd + Retry Prøv igen + Ignore Ignorer + Restore Defaults Gendan standardværdier + Close without Saving Luk uden at gemme @@ -1063,25 +1297,29 @@ to QDirModel - + Name Navn + Size Størrelse + Kind Match OS X Finder Type + Type All other platforms + Date Modified Ændringsdato @@ -1089,15 +1327,17 @@ to QDockWidget - + Close Luk + Dock LĂ¥st + Float Flydende @@ -1105,10 +1345,12 @@ to QDoubleSpinBox + More Mere + Less Mindre @@ -1116,23 +1358,27 @@ to QErrorMessage - + Debug Message: Debug-besked: + Warning: Advarsel: + Fatal Error: Fatal fejl: + &Show this message again &Vis denne besked igen + &OK @@ -1140,22 +1386,33 @@ to QFile + + Destination file exists Destinationsfil findes + + Cannot remove source file + Kan ikke fjerne kildefil + + + Cannot open %1 for input Kan ikke Ă¥bne %1 til input + Cannot open for output Kan ikke Ă¥bne til output + Failure to write block Kunne ikke skrive blok + Cannot create %1 for output Kunne ikke oprette %1 til output @@ -1163,32 +1420,44 @@ to QFileDialog + + All Files (*) Alle filer (*) + Directories Kataloger + + + + &Open &Ă…bn + + &Save &Gem + Open Ă…bn + %1 already exists. Do you want to replace it? %1 findes allerede. Ă˜nsker du at erstatte den? + %1 File not found. Please verify the correct file name was given. @@ -1197,47 +1466,64 @@ Filen kunne ikke findes. KontrollĂ©r, at det rigtige filnavn er indtastet. - + My Computer Min computer + &Rename &Omdøb + &Delete &Slet + Show &hidden files Vis s&kjulte filer + + Back Tilbage + + Parent Directory Ovenliggende katalog + + List View Listevisning + + Detail View Detaljevisning + + Files of type: Filer af typen: + + Directory: Katalog: + + %1 Directory not found. Please verify the correct directory name was given. @@ -1246,84 +1532,105 @@ Katalog kunne ikke findes. KontrollĂ©r, at det rigtige katalognavn er indtastet. + '%1' is write protected. Do you want to delete it anyway? '%1' er skrivebeskyttet. Ă˜nsker du alligevel at slette? + Are sure you want to delete '%1'? Er du sikker pĂ¥, at '%1' skal slettes? + Could not delete directory. Kunne ikke slette kataloget. + Recent Places Aktuelle steder - + All Files (*.*) Alle filer (*.*) + Save As Gem som - + Drive Drev + + File Fil + Unknown Ukendt + Find Directory Find katalog + Show Vis + + Forward Frem - + New Folder Ny folder + &New Folder &Ny folder + + &Choose &Vælg - + Remove Fjern + + File &name: &Filnavn: + + Look in: Søg i: + + Create New Folder Opret ny folder @@ -1331,62 +1638,74 @@ Do you want to delete it anyway? QFileSystemModel - + Invalid filename Ugyldigt filnavn + <b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks. <b>Navnet, %1, kan ikke benyttes.</b><p>Brug et andet navn med færre tegn og ingen kommatering. + Name Navn + Size Størrelse + Kind Match OS X Finder Type + Type All other platforms + Date Modified Ændringsdato - + My Computer Min computer + Computer + %1 TB %1 TB + %1 GB %1 GB + %1 MB %1 MB + %1 KB %1 KB' + %1 bytes %1 bytes @@ -1394,166 +1713,216 @@ Do you want to delete it anyway? QFontDatabase + + Normal + + + Bold Fed + + Demi Bold + + + Black Sort + Demi + + Light Lys + + Italic Kursiv + + Oblique SkrĂ¥t + Any Alle + Latin + Greek Græsk + Cyrillic Kyrillisk + Armenian Armensk + Hebrew Hebræisk + Arabic Arabisk + Syriac Syrisk + Thaana + Devanagari + Bengali Bengalsk + Gurmukhi + Gujarati + Oriya + Tamil + Telugu + Kannada + Malayalam + Sinhala + Thai Thailandsk + Lao + Tibetan Tibetansk + Myanmar + Georgian georgisk + Khmer + Simplified Chinese Forenklet kinesisk + Traditional Chinese Traditionelt kinesisk + Japanese Japansk + Korean Koreansk + Vietnamese Vietnamesisk + Symbol + Ogham + Runic @@ -1561,39 +1930,48 @@ Do you want to delete it anyway? QFontDialog - + &Font S&krifttype + Font st&yle S&til + &Size &Størrelse + Effects Effekter + Stri&keout &Overstreget + &Underline &Understreg + Sample Eksempel + Wr&iting System Skr&ivesystem + + Select Font Vælg skrifttype @@ -1601,116 +1979,145 @@ Do you want to delete it anyway? QFtp - + + Not connected Ingen forbindelse - + + Host %1 not found Vært %1 ikke fundet - + + Connection refused to host %1 Forbindelse til vært %1 afvist + Connection timed out to host %1 Forbindelsen timed out til host %1 + + + Connected to host %1 Tilsluttet vært %1 + + Connection refused for data connection Dataforbindelse afvist + + + + Unknown error Ukendt fejl - + + Connecting to host failed: %1 Forbindelse til vært mislykkedes: %1 - + + Login failed: %1 Login mislykkedes: %1 - + + Listing directory failed: %1 Opremsning af katalogindhold mislykkedes: %1 - + + Changing directory failed: %1 Ændring af katalog mislykkedes: %1 - + + Downloading file failed: %1 Downloading af fil mislykkedes: %1 - + + Uploading file failed: %1 Uploading af fil mislykkedes: %1 - + + Removing file failed: %1 Det mislykkedes at fjerne fil: %1 - + + Creating directory failed: %1 Oprettelse af katalog mislykkedes: %1 - + + Removing directory failed: %1 Det mislykkedes at fjerne katalog: %1 + + + Connection closed Forbindelse lukket + Host %1 found Vært %1 fundet + Connection to %1 closed Forbindelse til %1 lukket + Host found Vært fundet + Connected to host Tilsluttet vært @@ -1718,7 +2125,7 @@ Do you want to delete it anyway? QHostInfo - + Unknown error Ukendt fejl @@ -1726,14 +2133,29 @@ Do you want to delete it anyway? QHostInfoAgent + + + + + + + + Host not found Vært ikke fundet + + + + Unknown address type Ukendt adressetype + + + Unknown error Ukendt fejl @@ -1741,116 +2163,155 @@ Do you want to delete it anyway? QHttp + + + + Unknown error Ukendt fejl + + Request aborted Forespørgsel blev annulleret - + + No server set to connect to Ingen server at forbinde til - + + Wrong content length Forkert indholdslængde - + + Server closed connection unexpectedly Serveren afsluttede uventet forbindelsen + + Unknown authentication method + Ukendt autentifikationsmetode + + + Error writing response to device Skrivefejl mens der blev skrevet til enheden - + + Connection refused Forbindelse afvist - + + + Host %1 not found Vært %1 ikke fundet - + + + + HTTP request failed HTTP anmodning mislykkedes - + + Invalid HTTP response header Ugyldig HTTP-svar-header + + + + Invalid HTTP chunked body Ugyldig HTTP chunked body - + Host %1 found Vært %1 fundet + Connected to host %1 Tilsluttet vært %1 + Connection to %1 closed Forbindelse til %1 lukket + Host found Vært fundet + Connected to host Tilsluttet vært - + + Connection closed Forbindelse lukket + Proxy authentication required Kræver proxy-autentificering + Authentication required Autentificering pĂ¥krævet + Connection refused (or timed out) Forbindelse blev afvist (eller tid udløb) - + Proxy requires authentication Proxy kræver autentificering + Host requires authentication Vært kræver autentificering + Data corrupted Data er ødelagt + Unknown protocol specified En ukendt protokol blev angivet + SSL handshake failed SSL handshake mislykkedes + HTTPS connection requested but SSL support not compiled in Der blevet anmodet om en HTTPS-forbindelse, men SSL understøttelse er ikke kompileret ind @@ -1858,38 +2319,47 @@ Do you want to delete it anyway? QHttpSocketEngine + Did not receive HTTP response from proxy Modtog ikke HTTP-svar fra proxy + Error parsing authentication request from proxy Fejl under fortolking af autentificeringsanmodning fra proxy + Authentication required Autentificering pĂ¥krævet + Proxy denied connection Proxy nægtede forbindelse + Error communicating with HTTP proxy Fejl under kommunikation med HTTP-proxy + Proxy server not found Proxy-server kunne ikke findes + Proxy connection refused Proxy-forbindelse nægtede + Proxy server connection timed out Proxy-serverforbindelse timed out + Proxy connection closed prematurely Proxy-forbindelse afsluttede i utide @@ -1897,19 +2367,22 @@ Do you want to delete it anyway? QIBaseDriver - + Error opening database Der opstod fejl ved Ă¥bning af database + Could not start transaction Kunne ikke pĂ¥begynde transaktionen + Unable to commit transaction Kunne ikke gennemføre transaktionen + Unable to rollback transaction Kunne ikke tilbagetrække transaktionen @@ -1917,70 +2390,89 @@ Do you want to delete it anyway? QIBaseResult + Unable to create BLOB Kunne ikke oprette BLOB + Unable to write BLOB Kunne ikke skrive BLOB + Unable to open BLOB Kunne ikke Ă¥bne BLOB + Unable to read BLOB Kunne ikke læse BLOB + + Could not find array Kunne ikke finde array + Could not get array data Kunne ikke hente arraydata + Could not get query info Kunne ikke hente forespørgselsinfo + Could not start transaction Kunne ikke pĂ¥begynde transaktionen + Unable to commit transaction Kunne ikke gennemføre transaktionen + Could not allocate statement Kunne ikke allokere statement + Could not prepare statement Kunne ikke forberede udsagn + + Could not describe input statement Kunne ikke beskrive input-statement + Could not describe statement Kunne ikke beskrive statement + Unable to close statement Kunne ikke lukke udsagn + Unable to execute query Kunne ikke udføre forespørgsel + Could not fetch next item Kunne ikke hente næste element + Could not get statement info Kunne ikke hente udsagnsinformation @@ -1988,24 +2480,27 @@ Do you want to delete it anyway? QIODevice - + Permission denied Tilladelse nægtet + Too many open files Der er for mange Ă¥bne filer + No such file or directory Fil eller katalog findes ikke + No space left on device Ingen plads tilbage pĂ¥ enheden - + Unknown error Ukendt fejl @@ -2013,19 +2508,22 @@ Do you want to delete it anyway? QInputContext - + XIM + XIM input method XIM input-metode + Windows input method Windows input-metode + Mac OS X input method Mac OS X input-metode @@ -2033,7 +2531,7 @@ Do you want to delete it anyway? QInputDialog - + Enter a value: Indtast en værdi: @@ -2041,55 +2539,66 @@ Do you want to delete it anyway? QLibrary - + Could not mmap '%1': %2 + Plugin verification data mismatch in '%1' Plugin-verifikationsdata er sat forkert sammen i '%1' + Could not unmap '%1': %2 Der var ikke muligt at lave unmap pĂ¥ '%1': %2 + The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5] Plugin '%1' bruger inkompatibelt Qt-bibliotek. (%2.%3.%4) [%5] + The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3" Plugin '%1' bruger inkompatibelt Qt-bibliotek. Forventet build key "%2", hentede "%3"' + Unknown error Ukendt fejl' - + + The shared library was not found. DSO blev ikke fundet. + The file '%1' is not a valid Qt plugin. Filen '%1' er ikke et gyldigt Qt-plugin. + The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.) Plugin '%1' bruger inkompatibelt Qt-bibliotek. (Ikke muligt at mikse debug og release-biblioteker) - + + Cannot load library %1: %2 Kan ikke indlæse bibliotek %1: %2 - + + Cannot unload library %1: %2 Kan ikke afregistrere bibliotek %1: %2 - + + Cannot resolve symbol "%1" in %2: %3 Kan ikke løse symbol "%1" i %2: %3 @@ -2097,31 +2606,37 @@ Do you want to delete it anyway? QLineEdit - + &Undo &Fortryd + &Redo &Gendan + Cu&t K&lip + &Copy &KopiĂ©r + &Paste &Sæt ind + Delete Slet + Select All MarkĂ©r alt @@ -2129,20 +2644,24 @@ Do you want to delete it anyway? QLocalServer - + + %1: Name error %1: Navnefejl + %1: Permission denied %1: Tilladelse nægtet + %1: Address in use %1: Adresse i brug - + + %1: Unknown error %2 %1: Ukendt fejl %2 @@ -2150,54 +2669,70 @@ Do you want to delete it anyway? QLocalSocket - + + %1: Connection refused %1: Forbindelse afvist - + + %1: Remote closed %1: Den anden ende lukkede + + + + %1: Invalid name %1: Ugyldigt navn - + + %1: Socket access error %1: Fejl i socket-adgang - + + %1: Socket resource error %1: Fejl i socket-ressource - + + %1: Socket operation timed out %1: Socket-handling timed out - + + %1: Datagram too large %1: Datagram er for stort + + + %1: Connection error %1: Forbindelsesfejl - + + %1: The socket operation is not supported %1: Socket-handlingen understøttes ikke + %1: Unknown error %1: Ukendt fejl - + + %1: Unknown error %2 %1: Ukendt fejl %2 @@ -2205,23 +2740,27 @@ Do you want to delete it anyway? QMYSQLDriver - + Unable to open database ' Kunne ikke Ă¥bne databasen ' + Unable to connect Kunne ikke forbinde + Unable to begin transaction Kunne ikke pĂ¥begynde transaktionen + Unable to commit transaction Kunne ikke gennemføre transaktionen + Unable to rollback transaction Kunne ikke tilbagetrække transaktionen @@ -2229,46 +2768,59 @@ Do you want to delete it anyway? QMYSQLResult + Unable to fetch data Kunne ikke hente data + Unable to execute query Kunne ikke udføre forespørgsel + Unable to store result Kunne ikke gemme resultatet + + Unable to prepare statement Kunne ikke forberede udsagn + Unable to reset statement Kunne ikke nulstille udsagn + Unable to bind value Kunne ikke tildele værdi + Unable to execute statement Kunne ikke udføre udsagn + + Unable to bind outvalues Kunne ikke binde udværdier + Unable to store statement results Kunne ikke gemme udsagnsresultater + Unable to execute next query Kunne ikke udføre næste forespørgsel + Unable to store next result Kunne ikke gemme næste resultat @@ -2276,7 +2828,7 @@ Do you want to delete it anyway? QMdiArea - + (Untitled) (Uden titel) @@ -2284,75 +2836,92 @@ Do you want to delete it anyway? QMdiSubWindow - + %1 - [%2] + Close Luk + Minimize MinimĂ©r + Restore Down Gendan Ned + &Restore &Gendan + &Move &Flyt + &Size &Størrelse + Mi&nimize Mi&nimĂ©r + Ma&ximize Ma&ksimĂ©r + Stay on &Top Bliv &oppe + &Close &Luk + - [%1] + Maximize MaksimĂ©r + Unshade Fjern skygge + Shade Skygge + Restore Gendan + Help Hjælp + Menu @@ -2360,14 +2929,21 @@ Do you want to delete it anyway? QMenu + + Close Luk + + Open Ă…bn + + + Execute Udfør @@ -2375,42 +2951,55 @@ Do you want to delete it anyway? QMessageBox + Help Hjælp + + + + OK + + <h3>About Qt</h3><p>This program uses Qt version %1.</p><p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is available under three different licensing options designed to accommodate the needs of our various users.</p>Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.</p><p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.</p><p>Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.</p><p>Please see <a href="http://www.qtsoftware.com/products/licensing">www.qtsoftware.com/products/licensing</a> for an overview of Qt licensing.</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>Qt is a Nokia product. See <a href="http://www.qtsoftware.com/qt/">www.qtsoftware.com/qt</a> for more information.</p> + <h3>Om Qt</h3><p>Dette program anvender Qt version %1.</p><p>Qt er et C++ toolkit til cross-platform applikationsudvikling.</p><p>Qt tilbyder single-source portabilitet til MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, og alle større kommercielle Unix-varianter. Qt er ogsĂ¥ tilgængeligt til indlejrede systemer som Qt for Embedded Linux and Qt for Windows CE.</p>Qt er tilgængeligt under tre forskellige licenser skabt med henblik pĂ¥ at imødekomme forskellige brugeres behov.</p><p>Qt licenseret under vores kommercielle licensaftale er passende for udvikling af proprietær/kommerciel software, hvor du ikke ønsker at dele sourcekode med tredie part, eller pĂ¥ anden vis ikke kan tiltræde vilkĂ¥rerne i GNU LGPL version 2.1 eller GNU GPL version 3.0</p><p>Qt licenseret under GLU General Public License version 3.0 er passende for udvikling af Qt applikationer, hvor du ønsker at bruge softwaren i kombination med software under vilkĂ¥rerne i GNU GPL version 3.0, eller hvor du ellers er villig til at overholde vilkĂ¥rerne i GNU GPL version 3.0</p><p>See venligst <a href="http://www.qtsoftware.com/products/licensing">www.qtsoftware.com/products/licensing</a> for et overblik over Qt licensforhold.</p><p>Qt er et Nokia produkt. Se <a href="http://qtsoftware.com/qt/">qtsoftware.com/qt/</a> for yderligere information.</p> + + + About Qt Om Qt <p>This program uses Qt version %1.</p> - <p>Dette program bruger Qt-version %1.</p> + <p>Dette program bruger Qt-version %1.</p> + Show Details... Vis detaljer... + Hide Details... Skjul detaljer... <h3>About Qt</h3>%1<p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is a Nokia product. See <a href="http://qtsoftware.com/qt/">qtsoftware.com/qt/</a> for more information.</p> - <h3>Om Qt</h3>%1<p>Qt er et C++ toolkit til cross-platform applikationsudvikling.</p><p>Qt tilbyder single-source portabilitet til MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, og alle større kommercielle Unix-varianter. Qt er ogsĂ¥ tilgængeligt til indlejrede systemer som Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt er et Nokia produkt. Se <a href="http://qtsoftware.com/qt/">qtsoftware.com/qt/</a> for yderligere information.</p> + <h3>Om Qt</h3>%1<p>Qt er et C++ toolkit til cross-platform applikationsudvikling.</p><p>Qt tilbyder single-source portabilitet til MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, og alle større kommercielle Unix-varianter. Qt er ogsĂ¥ tilgængeligt til indlejrede systemer som Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt er et Nokia produkt. Se <a href="http://qtsoftware.com/qt/">qtsoftware.com/qt/</a> for yderligere information.</p> <p>This program uses Qt Open Source Edition version %1.</p><p>Qt Open Source Edition is intended for the development of Open Source applications. You need a commercial Qt license for development of proprietary (closed source) applications.</p><p>Please see <a href="http://qtsoftware.com/company/model/">qtsoftware.com/company/model/</a> for an overview of Qt licensing.</p> - <p>Dette program bruger Qt Open Source Edition version %1.</p><p>Qt Open Source Edition er beregnet til udvikling af Open Source applikationer. En kommerciel Qt licens er nødvendig til udvikling af proprietære (lukket sourcekode) applikationer.</p><p>Se venligst <a href="http://qtsoftware.com/company/model/">qtsoftware.com/company/model/</a> for et overblik over Qt licensforhold.</p> + <p>Dette program bruger Qt Open Source Edition version %1.</p><p>Qt Open Source Edition er beregnet til udvikling af Open Source applikationer. En kommerciel Qt licens er nødvendig til udvikling af proprietære (lukket sourcekode) applikationer.</p><p>Se venligst <a href="http://qtsoftware.com/company/model/">qtsoftware.com/company/model/</a> for et overblik over Qt licensforhold.</p> QMultiInputContext - + Select IM MarkĂ©r IM @@ -2418,11 +3007,12 @@ Do you want to delete it anyway? QMultiInputContextPlugin - + Multiple input method switcher Multiple input metode-switcher + Multiple input method switcher that uses the context menu of the text widgets Multiple input metode-switcher, der benytter tekstkontrollernes kontekstmenuer @@ -2430,107 +3020,132 @@ Do you want to delete it anyway? QNativeSocketEngine - + The remote host closed the connection Fjern-hosten lukkede forbindelsen + Network operation timed out Netværksoperationen timed out + Out of resources Ikke flere ressourcer + Unsupported socket operation Socket-operation ikke understøttet + Protocol type not supported Protokoltypen understøttes ikke + Invalid socket descriptor Ugyldig socket-deskriptor + Network unreachable Netværket er ikke tilgængeligt + Permission denied Tilladelse nægtet + Connection timed out Forbindelsen timed out + Connection refused Forbindelse afvist + The bound address is already in use Den bundne adresse er allerede i brug + The address is not available Adressen er ikke tilgængelig + The address is protected Adressen er beskyttet + Unable to send a message Kunne ikke sende en besked + Unable to receive a message Kunne ikke modtage en besked + Unable to write Kunne ikke skrive + Network error Netværksfejl + Another socket is already listening on the same port En anden socket lytter allerede pĂ¥ samme port + Unable to initialize non-blocking socket Kunne ikke initialisere non-blocking socket + Unable to initialize broadcast socket Kunne ikke initialisere broadcast-socket + Attempt to use IPv6 socket on a platform with no IPv6 support Forsøg pĂ¥ at bruge IPv6-socket pĂ¥ en platform uden IPv6-support + Host unreachable Vært er ikke tilgængelig + Datagram was too large to send Datagrammet var for stort til at blive sendt + Operation on non-socket Handling pĂ¥ non-socket + Unknown error Ukendt fejl + The proxy type is invalid for this operation Proxytypen er ugyldig til denne handling @@ -2538,7 +3153,7 @@ Do you want to delete it anyway? QNetworkAccessCacheBackend - + Error opening %1 Der opstod fejl i at Ă¥bne %1 @@ -2546,23 +3161,27 @@ Do you want to delete it anyway? QNetworkAccessFileBackend - + Request for opening non-local file %1 Anmodning om at Ă¥bne ikke-lokal fil %1 + Error opening %1: %2 Der opstod fejl i at Ă¥bne %1: %2 + Write error writing to %1: %2 Skrivefejl mens der blev skrevet til %1: %2 + Cannot open %1: Path is a directory Kan ikke Ă¥bne %1: Stien er et katalog + Read error reading from %1: %2 Læsefejl mens der blev læst fra %1: %2 @@ -2570,23 +3189,27 @@ Do you want to delete it anyway? QNetworkAccessFtpBackend - + No suitable proxy found Ingen passende proxy blev fundet + Cannot open %1: is a directory Kan ikke Ă¥bne %1: Er et katalog + Logging in to %1 failed: authentication required Der opstod fejl i at logge pĂ¥ %1: Autentificering kræves + Error while downloading %1: %2 Der opstod fejl i at downloade %1: %2 + Error while uploading %1: %2 Der opstod fejl i at uploade %1: %2 @@ -2594,7 +3217,7 @@ Do you want to delete it anyway? QNetworkAccessHttpBackend - + No suitable proxy found Ingen passende proxy blev fundet @@ -2602,11 +3225,12 @@ Do you want to delete it anyway? QNetworkReply + Error downloading %1 - server replied: %2 Der opstod fejl i at downloade %1 - serveren svarede: %2 - + Protocol "%1" is unknown Protokollen "%1" er ukendt @@ -2614,6 +3238,8 @@ Do you want to delete it anyway? QNetworkReplyImpl + + Operation canceled Handling blev annulleret @@ -2621,24 +3247,28 @@ Do you want to delete it anyway? QOCIDriver - + Unable to logon Kunne ikke logge pĂ¥ + Unable to initialize QOCIDriver Kunne ikke initialisere + Unable to begin transaction Kunne ikke pĂ¥begynde transaktionen + Unable to commit transaction Kunne ikke gennemføre transaktionen + Unable to rollback transaction Kunne ikke tilbagetrække transaktionen @@ -2646,34 +3276,43 @@ Do you want to delete it anyway? QOCIResult + + + Unable to bind column for batch execute Kunne ikke tildele kolonne til batch-udførsel + Unable to execute batch statement Kunne ikke udføre batch-udsagn + Unable to goto next Kunne ikke gĂ¥ til den næste + Unable to alloc statement Kunne ikke allokere udsagn + Unable to prepare statement Kunne ikke forberede udsagn + Unable to bind value Kunne ikke tildele værdi Unable to execute select statement - Kunne ikke udføre det valgte udsagn + Kunne ikke udføre det valgte udsagn + Unable to execute statement Kunne ikke udføre udsagn @@ -2681,27 +3320,32 @@ Do you want to delete it anyway? QODBCDriver - + Unable to connect Kunne ikke forbinde + Unable to connect - Driver doesn't support all needed functionality Kunne ikke forbinde. Driveren understøtter ikke alle de nødvendige funktionaliteter + Unable to disable autocommit Kunne ikke slĂ¥ auto-udfør fra + Unable to commit transaction Kunne ikke gennemføre transaktionen + Unable to rollback transaction Kunne ikke tilbagetrække transaktionen + Unable to enable autocommit Kunne ikke slĂ¥ auto-udfør til @@ -2709,38 +3353,51 @@ Do you want to delete it anyway? QODBCResult + + QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration QODBCResult::reset: Kunne ikke indstille 'SQL_CURSOR_STATIC' til udsagnsattribut. KontrollĂ©r ODBC-driver-konfigurationen + + Unable to execute statement Kunne ikke udføre udsagn + Unable to fetch next Kunne ikke hente den næste + Unable to prepare statement Kunne ikke forberede udsagn + Unable to bind variable Kunne ikke tildele variabel + + + Unable to fetch last Kunne ikke hente den sidste + Unable to fetch Kunne ikke hente + Unable to fetch first Kunne ikke hente den første + Unable to fetch previous Kunne ikke hente den forrige @@ -2748,41 +3405,48 @@ Do you want to delete it anyway? QObject - + Home Hjem - + Operation not supported on %1 Handling blev ikke understøttet pĂ¥ %1 + Invalid URI: %1 Ugyldig URI: %1 - + Write error writing to %1: %2 Skrivefejl mens der blev skrevet til %1: %2 + Read error reading from %1: %2 Læsefejl mens der blev læst fra %1: %2 + Socket error on %1: %2 Socket-fejl pĂ¥ %1: %2 + Remote host closed the connection prematurely on %1 Fjern-host lukkede forbindelsen for tidligt pĂ¥ %1 + Protocol error: packet of size 0 received Protokolfejl: Pakke pĂ¥ størrelsen 0 modtaget + + No host name given Hostnavn mangler @@ -2790,11 +3454,12 @@ Do you want to delete it anyway? QPPDOptionsModel - + Name Navn + Value Værdi @@ -2802,27 +3467,32 @@ Do you want to delete it anyway? QPSQLDriver - + Unable to connect Kunne ikke skabe forbindelse + Could not begin transaction Kunne ikke pĂ¥begynde transaktion + Could not commit transaction Kunne ikke gennemføre transaktion + Could not rollback transaction Kunne ikke tilbagetrække transaktion + Unable to subscribe Kunne ikke tilmelde + Unable to unsubscribe Kunne ikke afmelde @@ -2830,10 +3500,12 @@ Do you want to delete it anyway? QPSQLResult + Unable to create query Kunne ikke oprette forespørgsel + Unable to prepare statement Kunne ikke forberede udsagn @@ -2841,83 +3513,102 @@ Do you want to delete it anyway? QPageSetupWidget - + Centimeters (cm) Centimeter (cm) + Millimeters (mm) Millimeter (mm) + Inches (in) + Points (pt) Point (pt) + Form + Paper Papir + Page size: Sidestørrelse: + Width: Vidde: + Height: Højde: + Paper source: Papirkilde: + Orientation + Portrait Portræt + Landscape Landskab + Reverse landscape Omvendt landskab + Reverse portrait Omvendt portræt + Margins Margener + top margin Margen - øverst + left margin Margen - venstre + right margin Margen - højre + bottom margin Margen - bund @@ -2925,11 +3616,12 @@ Do you want to delete it anyway? QPluginLoader - + Unknown error Ukendt fejl + The plugin was not loaded. Plugin blev ikke indlæst. @@ -2937,346 +3629,428 @@ Do you want to delete it anyway? QPrintDialog - + locally connected lokalt forbundet + + Aliases: %1 Aliasser: %1 + + unknown Ukendt - + A0 (841 x 1189 mm) + A1 (594 x 841 mm) + A2 (420 x 594 mm) + A3 (297 x 420 mm) + A4 (210 x 297 mm, 8.26 x 11.7 inches) + A5 (148 x 210 mm) + A6 (105 x 148 mm) + A7 (74 x 105 mm) + A8 (52 x 74 mm) + A9 (37 x 52 mm) + B0 (1000 x 1414 mm) + B1 (707 x 1000 mm) + B2 (500 x 707 mm) + B3 (353 x 500 mm) + B4 (250 x 353 mm) + B5 (176 x 250 mm, 6.93 x 9.84 inches) + B6 (125 x 176 mm) + B7 (88 x 125 mm) + B8 (62 x 88 mm) + B9 (44 x 62 mm) + B10 (31 x 44 mm) + C5E (163 x 229 mm) + DLE (110 x 220 mm) + Executive (7.5 x 10 inches, 191 x 254 mm) + Folio (210 x 330 mm) + Ledger (432 x 279 mm) + Legal (8.5 x 14 inches, 216 x 356 mm) + Letter (8.5 x 11 inches, 216 x 279 mm) + Tabloid (279 x 432 mm) + US Common #10 Envelope (105 x 241 mm) - + OK + + + Print Udskriv + Print To File ... Udskriv til fil... - + Print range UdskriftsomrĂ¥de + Print all Udskriv alle - + File %1 is not writable. Please choose a different file name. Filen %1 kan ikke skrives. Vælg et andet filnavn. + %1 already exists. Do you want to overwrite it? %1 findes allerede. Ă˜nsker du at overskrive? + File exists Fil findes + <qt>Do you want to overwrite it?</qt> <qt>Ă˜nsker du at overskrive?</qt> + Print selection Udskriv markerede + %1 is a directory. Please choose a different file name. %1 er et katalog. Vælg et andet filnavn. + A0 + A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + B0 + B1 + B2 + B3 + B4 + B5 + B6 + B7 + B8 + B9 + B10 + C5E + DLE + Executive + Folio + Ledger + Legal + Letter + Tabloid + US Common #10 Envelope + Custom Brugerdefineret + + &Options >> &Indstillinger>> + &Print &Udskriv + &Options << &Indstillinger<< + Print to File (PDF) Udskriv til fil (PDF) + Print to File (Postscript) Udskriv til fil (Postscript) + Local file Lokal fil + Write %1 file Skriv %1 fil - + The 'From' value cannot be greater than the 'To' value. 'Fra'-værdien kan ikke være større end 'til'-værdien. @@ -3284,87 +4058,108 @@ Vælg et andet filnavn. QPrintPreviewDialog + + Page Setup Sideopsætning - + %1% + Print Preview Vis udskrift + Next page Næste side + Previous page Forrige side + First page Første side + Last page Sidste side + Fit width Tilpas bredde + Fit page Tilpas siden + Zoom in Zoom ind + Zoom out Zoom ud + Portrait Portræt + Landscape Landskab + Show single page Vis enkelt side + Show facing pages Vis sideopslag + Show overview of all pages Vis oversigt af alle sider + Print Udskriv + Page setup Sideopsætning + Close Luk + Export to PDF EksportĂ©r til PDF + Export to PostScript EksportĂ©r til PostScript @@ -3372,14 +4167,17 @@ Vælg et andet filnavn. QPrintPropertiesWidget + Form Form + Page Side + Advanced Avanceret @@ -3387,78 +4185,97 @@ Vælg et andet filnavn. QPrintSettingsOutput + Form + Copies Kopier + Print range Udskriv sider + Print all Udskriv alle + Pages from Sider fra + to til + Selection Valg + Output Settings Udskriftsindstillinger + Copies: Kopier: + Collate Samordne + Reverse Omvendt + Options Valgmuligheder + Color Mode Farvetilstand + Color Farve + Grayscale GrĂ¥skala + Duplex Printing Dobbelsidet + None Ingen + Long side Bog + Short side Tavle @@ -3466,38 +4283,47 @@ Vælg et andet filnavn. QPrintWidget + Form + Printer ' + &Name: &Navn: + P&roperties &Egenskaber + Location: Placering: + Preview Vis udskrift + Type: + Output &file: Udskrifts&fil: + ... @@ -3505,37 +4331,62 @@ Vælg et andet filnavn. QProcess - + + Could not open input redirection for reading Kunne ikke Ă¥bne input redirection for læsning - + + Could not open output redirection for writing Kunne ikke Ă¥bne output redirection for skrivning + Resource error (fork failure): %1 Ressource fejl (fork fejl): %1 + + + + + + + + + Process operation timed out Proces-operation time out + + + + Error reading from process Fejl ved læsning fra proces - + + + Error writing to process Fejl ved skrivning til proces + Process crashed Proces crashede + + No program defined + Intet program defineret + + + Process failed to start Processen kunne ikke starte @@ -3543,7 +4394,7 @@ Vælg et andet filnavn. QProgressDialog - + Cancel Annuller @@ -3551,6 +4402,7 @@ Vælg et andet filnavn. QPushButton + Open Ă…bn @@ -3558,6 +4410,7 @@ Vælg et andet filnavn. QRadioButton + Check KontrollĂ©r @@ -3565,39 +4418,47 @@ Vælg et andet filnavn. QRegExp - + no error occurred der opstod ingen fejl + disabled feature used deaktiveret funktion blev brugt + bad char class syntax dĂ¥rlig char class syntaks + bad lookahead syntax dĂ¥rlig lookahead syntaks + bad repetition syntax dĂ¥rlig gentagelsessyntaks + invalid octal value ugyldigt oktal-tal + missing left delim Manglende venstre delimiter + unexpected end uventet afslutning + met internal limit nĂ¥ede interne grænse @@ -3605,19 +4466,22 @@ Vælg et andet filnavn. QSQLite2Driver - + Error to open database Der opstod fejl ved Ă¥bning af database + Unable to begin transaction Kunne ikke pĂ¥begynde transaktionen + Unable to commit transaction Kunne ikke gennemføre transaktionen + Unable to rollback Transaction Kunne ikke tilbagetrække transaktion @@ -3625,10 +4489,12 @@ Vælg et andet filnavn. QSQLite2Result + Unable to fetch results Kunne ikke hente resultater + Unable to execute statement Kunne ikke udføre statement @@ -3636,23 +4502,27 @@ Vælg et andet filnavn. QSQLiteDriver - + Error opening database Der opstod fejl ved Ă¥bning af database + Error closing database Der opstod fejl ved lukning af database + Unable to begin transaction Kunne ikke pĂ¥begynde transaktionen + Unable to commit transaction Kunne ikke gennemføre transaktion + Unable to rollback transaction Kunne ikke tilbagetrække transaktion @@ -3660,26 +4530,34 @@ Vælg et andet filnavn. QSQLiteResult + + + Unable to fetch row Kunne ikke hente række + Unable to execute statement Kunne ikke udføre udsagn + Unable to reset statement Kunne ikke nulstille udsagn + Unable to bind parameters Unable to bind parameters + Parameter count mismatch Misforhold i parametertælling + No query Ingen forespørgesel @@ -3687,69 +4565,84 @@ Vælg et andet filnavn. QScrollBar - + Scroll here Scroll her + Left edge Venstre kant + Top Ă˜verst + Right edge Højre kant + Bottom Bund + Page left Side venstre - + + Page up Side øverst + Page right Side højre - + + Page down Side ned + Scroll left Scroll til venstre + Scroll up Scroll op + Scroll right Scroll til højre + Scroll down Scroll ned + Line up Linie op + Position Placering + Line down Linie ned @@ -3757,81 +4650,99 @@ Vælg et andet filnavn. QSharedMemory - + %1: unable to set key on lock %1: Kunne ikke oprette nøgle + %1: create size is less then 0 %1: create size is less then 0 - + + %1: unable to lock %1: Kunne ikke lĂ¥se + %1: unable to unlock %1: Kunne ikke oprette nøgle - + + %1: permission denied %1: Tilladelse nægtet + + %1: already exists %1: Findes allerede - + + %1: doesn't exists %1: Findes ikke - + + %1: out of resources %1: Ikke flere ressourcer - + + %1: unknown error %2 %1: ukendt fejl %2 + %1: key is empty %1: nøgle er tom + %1: unix key file doesn't exists %1: Kunne ikke oprette nøgle + %1: ftok failed %1: ftok mislykkedes - + + %1: unable to make key %1: Kunne ikke oprette nøgle + %1: system-imposed size restrictions %1: System-pĂ¥lagte størrelsesrestriktioner + %1: not attached %1: Ikke vedhæftet + %1: invalid size %1: Ugyldig størrelse + %1: key error %1: Nøglefejl + %1: size query failed %1: Størrelsesforespørgsel mislykkedes @@ -3839,371 +4750,466 @@ Vælg et andet filnavn. QShortcut - + Space + Esc + Tab + Backtab Tilbage-tabulator + Backspace Tilbage + Return + Enter + Ins + Del + Pause + Print Udskriv + SysReq + Home + End + Left Venstre + Up Op + Right Højre + Down Ned + PgUp + PgDown + CapsLock ' + NumLock + ScrollLock + Menu + Help Hjælp + Back Tilbage + Forward Frem + Stop + Refresh Opdater + Volume Down Lydstyrke ned + Volume Mute Lydstyrke mute + Volume Up Lydstyrke op + Bass Boost + Bass Up Bass op + Bass Down Bass ned + Treble Up Diskant op + Treble Down Diskant ned + Media Play + Media Stop + Media Previous Media forrige + Media Next Media næste + Media Record + Favorites + Search Søg + Standby + Open URL Ă…bn URL + Launch Mail Start mail + Launch Media Start Media + Launch (0) Start (0) + Launch (1) Start (1) + Launch (2) Start (2) + Launch (3) Start (3) + Launch (4) Start (4) + Launch (5) Start (5) + Launch (6) Start (6) + Launch (7) Start (7) + Launch (8) Start (8) + Launch (9) Start (9) + Launch (A) Start (A) + Launch (B) Start (B) + Launch (C) Start (C) + Launch (D) Start (D) + Launch (E) Start (E) + Launch (F) Start (F) + Print Screen + Page Up + Page Down + Caps Lock + Num Lock + Number Lock + Scroll Lock + Insert + Delete + Escape + System Request + Select Væg + Yes Ja + No Nej + Context1 Kontekst1 + Context2 Kontekst2 + Context3 Kontekst3 + Context4 Kontekst4 + Call Ring til + Hangup Læg pĂ¥ + Flip Vend + + Ctrl + + Shift + + Alt + + Meta + + + F%1 + Home Page Startside @@ -4211,23 +5217,27 @@ Vælg et andet filnavn. QSlider - + Page left Side venstre + Page up Side op + Position Placering + Page right Side højre + Page down Side ned @@ -4235,58 +5245,72 @@ Vælg et andet filnavn. QSocks5SocketEngine + Connection to proxy refused Proxy-forbindelse nægtede + Connection to proxy closed prematurely Proxy-forbindelse afsluttede i utide + Proxy host not found Proxy-host kunne ikke findes + Connection to proxy timed out Proxy-serverforbindelse timed out + Proxy authentication failed Proxy autentificering mislykkedes + Proxy authentication failed: %1 Proxy autentificering mislykkedes: %1 + SOCKS version 5 protocol error SOCKS version 5 protokolfejl + General SOCKSv5 server failure General SOCKSv5 serverfejl + Connection not allowed by SOCKSv5 server Forbindelse ikke tilladt a SOCKSv5-server + TTL expired TTL udløbet + SOCKSv5 command not supported SOCKSv5-kommando ikke understøttet + Address type not supported Adressetype understøttes ikke + Unknown SOCKSv5 proxy error code 0x%1 Ukendt SOCKSv5 proxy fejlkode 0x%1 + Network operation timed out Netværksoperationen timed out @@ -4294,10 +5318,12 @@ Vælg et andet filnavn. QSpinBox + More Mere + Less Mindre @@ -4305,43 +5331,56 @@ Vælg et andet filnavn. QSql - + Delete Slet + Delete this record? Slet denne post? + + + Yes Ja + + + No Nej + Insert Indsæt + Update Opdater + Save edits? Gem ændringer? + Cancel Annuller + Confirm Bekræft + Cancel your edits? Skal dine ændringer annulleres? @@ -4349,47 +5388,57 @@ Vælg et andet filnavn. QSslSocket - + Unable to write data: %1 Kunne ikke skrive data: %1 + Error while reading: %1 Der opstod en fejl under læsning af: %1 + Error during SSL handshake: %1 Der opstod en fejl under SSL handshake: %1 + Error creating SSL context (%1) Der opstod fejl under oprettelse af SSL-kontekst (%1) + Invalid or empty cipher list (%1) Ugyldig eller tom chifferliste (%1) + Error creating SSL session, %1 Der opstod fejl under oprettelse af SSL-session, %1 + Error creating SSL session: %1 Der opstod fejl under oprettelse af SSL-session, %1 + Cannot provide a certificate with no key, %1 Kan ikke give et certifikat uden nøgle, %1 + Error loading local certificate, %1 Der opstod fejl under indlæsning af lokalt certifikat, %1 + Error loading private key, %1 Der opstod fejl under indlæsning af privat nøgle, %1 + Private key does not certificate public key, %1 Privat-nøgle autoriserer ikke offentlig-nøgle, %1 @@ -4397,25 +5446,30 @@ Vælg et andet filnavn. QSystemSemaphore - + + %1: out of resources %1: Ikke flere ressourcer - + + %1: permission denied %1: Tilladelse nægtet + %1: already exists %1: Findes allerede + %1: does not exist %1: Findes ikke - + + %1: unknown error %2 %1: Ukendt fejl %2 @@ -4423,11 +5477,12 @@ Vælg et andet filnavn. QTDSDriver - + Unable to open connection Kunne ikke etablere forbindelsen + Unable to use database Kunne ikke bruge databasen @@ -4435,10 +5490,12 @@ Vælg et andet filnavn. QTabBar + Scroll Left Scroll til venstre + Scroll Right Scroll til højre @@ -4446,7 +5503,7 @@ Vælg et andet filnavn. QTcpServer - + Operation on socket is not supported Socket-operation ikke understøttet @@ -4454,35 +5511,42 @@ Vælg et andet filnavn. QTextControl - + &Undo &Fortryd + &Redo &Gendan + Cu&t K&lip + &Copy &KopiĂ©r + Copy &Link Location KopiĂ©r l&ink + &Paste &Sæt ind + Delete Slet + Select All MarkĂ©r alt @@ -4490,10 +5554,14 @@ Vælg et andet filnavn. QToolButton + + Press Tryk pĂ¥ + + Open Ă…bn @@ -4501,7 +5569,7 @@ Vælg et andet filnavn. QUdpSocket - + This platform does not support IPv6 Denne platform understøtter ikke IPv6 @@ -4509,11 +5577,12 @@ Vælg et andet filnavn. QUndoGroup - + Undo Fortryd + Redo Gendan @@ -4521,7 +5590,7 @@ Vælg et andet filnavn. QUndoModel - + <empty> <tom> @@ -4529,11 +5598,12 @@ Vælg et andet filnavn. QUndoStack - + Undo Fortryd + Redo Gendan @@ -4541,47 +5611,57 @@ Vælg et andet filnavn. QUnicodeControlCharacterMenu - + LRM Left-to-right mark + RLM Right-to-left mark + ZWJ Zero width joiner + ZWNJ Zero width non-joiner + ZWSP Zero width space + LRE Start of left-to-right embedding + RLE Start of right-to-left embedding + LRO Start of left-to-right override + RLO Start of right-to-left override + PDF Pop directional formatting + Insert Unicode control character @@ -4589,27 +5669,32 @@ Vælg et andet filnavn. QWebFrame - + Request cancelled Anmodning annulleret + Request blocked Anmodning blokeret + Cannot show URL Kan ikke vise URL + Frame load interruped by policy change Billedindlæsning afbrudt af ændringer i retningslinier + Cannot show mimetype Kan ikke vise MIME-type + File does not exist Filen findes ikke @@ -4617,316 +5702,376 @@ Vælg et andet filnavn. QWebPage - + Bad HTTP request DĂ¥rlig HTTP-anmodning - + Submit default label for Submit buttons in forms on web pages Send + Submit Submit (input element) alt text for <input> elements with no alt, title, or value Send + Reset default label for Reset buttons in forms on web pages Nulstil + This is a searchable index. Enter search keywords: text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index' Dette er et søgeindeks. Indtast søgeord: + Choose File title for file button used in HTML forms Vælg fil + No file selected text to display in file button used in HTML forms when no file is selected Der er ikke valgt en fil + Open in New Window Open in New Window context menu item Ă…bn i nyt vindue + Save Link... Download Linked File context menu item Gem link... + Copy Link Copy Link context menu item KopiĂ©r link + Open Image Open Image in New Window context menu item Ă…bn billede + Save Image Download Image context menu item Gem billede + Copy Image Copy Link context menu item KopiĂ©r billede + Open Frame Open Frame in New Window context menu item Ă…bn faneblad + Copy Copy context menu item KopiĂ©r + Go Back Back context menu item GĂ¥ tilbage + Go Forward Forward context menu item GĂ¥ frem + Stop Stop context menu item Stop + Reload Reload context menu item Genindlæs + Cut Cut context menu item Klip + Paste Paste context menu item Sæt ind + No Guesses Found No Guesses Found context menu item Der er ikke fundet nogen gæt + Ignore Ignore Spelling context menu item IgnorĂ©r + Add To Dictionary Learn Spelling context menu item Tilføj til ordbog + Search The Web Search The Web context menu item Søg pĂ¥ nettet + Look Up In Dictionary Look Up in Dictionary context menu item SlĂ¥ op i ordbog + Open Link Open Link context menu item Ă…bn link + Ignore Ignore Grammar context menu item IgnorĂ©r + Spelling Spelling and Grammar context sub-menu item Stavekontrol + Show Spelling and Grammar menu item title Vis stave- og grammatikkontrol + Hide Spelling and Grammar menu item title Skjul stave- og grammatikkontrol + Check Spelling Check spelling context menu item Kør stavekontrol + Check Spelling While Typing Check spelling while typing context menu item Kør stavekontrol mens der tastes + Check Grammar With Spelling Check grammar with spelling context menu item Kør grammatikkontrol sammen med stavekontrol + Fonts Font context sub-menu item Skrifttyper + Bold Bold context menu item Fed + Italic Italic context menu item Kursiv + Underline Underline context menu item Understreget + Outline Outline context menu item Kontur + Direction Writing direction context sub-menu item Retning + Text Direction Text direction context sub-menu item Tekstretning + Default Default writing direction context menu item Standard + LTR Left to Right context menu item + RTL Right to Left context menu item + Inspect Inspect Element context menu item InspicĂ©r + No recent searches Label for only item in menu that appears when clicking on the search field image, when no searches have been performed Ingen aktuelle søgninger + Recent searches label for first item in the menu that appears when clicking on the search field image, used as embedded menu title Aktuelle søgninger + Clear recent searches menu item in Recent Searches menu that empties menu's contents Ryd aktuelle søgninger + Unknown Unknown filesize FTP directory listing item Ukendt + %1 (%2x%3 pixels) Title string for images %1 (%2x%3 pixels) - + Web Inspector - %2 Web-inspektør - %2 - + Scroll here Scroll her + Left edge Venstre kant + Top + Right edge Højre kant + Bottom Bund + Page left Side venstre + Page up Side øverst + Page right Side højre + Page down Side ned + Scroll left Scroll til venstre + Scroll up Scroll op + Scroll right Scroll til højre + Scroll down Scroll ned - + %n file(s) number of chosen file @@ -4935,127 +6080,170 @@ Vælg et andet filnavn. - + JavaScript Alert - %1 JavaScript alert - %1 + JavaScript Confirm - %1 JavaScript Bekræft - %1 + JavaScript Prompt - %1 JavaScript Prompt - %1 + Move the cursor to the next character Flyt markør til næste tegn + Move the cursor to the previous character Flyt markør til forrige tegn + Move the cursor to the next word Flyt markør til næste ord + Move the cursor to the previous word Flyt markør til forrige ord + Move the cursor to the next line Flyt markør til næste linie + Move the cursor to the previous line Flyt markør til forrige linie + Move the cursor to the start of the line Flyt markør til starten af linien + Move the cursor to the end of the line Flyt markør til slutningen af linien + Move the cursor to the start of the block Flyt markør til starten af sektionen + Move the cursor to the end of the block Flyt markør til slutningen af sektionen + Move the cursor to the start of the document Flyt markør til starten af dokumentet + Move the cursor to the end of the document Flyt markør til slutningen af dokumentet + + Select all + MarkĂ©r alt + + + Select to the next character Vælg til næste tegn + Select to the previous character Vælg til forrige tegn + Select to the next word Vælg til næste ord + Select to the previous word Vælg til forrige ord + Select to the next line Vælg til næste linie + Select to the previous line Vælg til forrige linie + Select to the start of the line Vælg til starten af linien + Select to the end of the line Vælg til slutningen af linien + Select to the start of the block Vælg til starten af sektionen + Select to the end of the block Vælg til slutningen af sektionen + Select to the start of the document Vælg til starten af dokumentet + Select to the end of the document Vælg til slutningen af dokumentet + Delete to the start of the word Slet til starten af ordet + Delete to the end of the word Slet til slutningen af ordet + + + Insert a new paragraph + Indsæt et nyt afsnit + + + + Insert a new line + Insert ny linie + QWhatsThisAction - + What's This? Hvad er dette? @@ -5063,7 +6251,7 @@ Vælg et andet filnavn. QWidget - + * @@ -5071,47 +6259,57 @@ Vælg et andet filnavn. QWizard - + Go Back GĂ¥ tilbage + Continue Fortsæt + Commit Udfør + Done Færdig + Help Hjælp + < &Back < &Tilbage + &Finish &Afslut + Cancel Annuller + &Help &Hjælp + &Next &Næste + &Next > &Næste > @@ -5119,55 +6317,69 @@ Vælg et andet filnavn. QWorkspace - + &Restore &Gendan + &Move &Flyt + &Size &Størrelse + Mi&nimize Mi&nimĂ©r + Ma&ximize Ma&ksimĂ©r + &Close &Luk + Stay on &Top Bliv pĂ¥ &toppen + + Sh&ade Sk&ygge + + %1 - [%2] + Minimize Minimer + Restore Down Gendan ned + Close Luk + &Unshade &Fjern skygge @@ -5175,95 +6387,117 @@ Vælg et andet filnavn. QXml - + no error occurred der opstod ingen fejl + error triggered by consumer - + Fejltilstand rejst af datamodtager + unexpected end of file uventet afslutning pĂ¥ fil + more than one document type definition mere end Ă©n definition pĂ¥ dokumenttype + error occurred while parsing element der opstod fejl under fortolking af element + tag mismatch + error occurred while parsing content der opstod fejl under fortolking af indhold + unexpected character uventet tegn + invalid name for processing instruction - + Ugyldigt navn for processing instruction + version expected while reading the XML declaration version forventet under læsning af XML-deklaration + wrong value for standalone declaration - + Forkert værdi for fri deklaration + encoding declaration or standalone declaration expected while reading the XML declaration - + Enkodningsdeklaration eller fri deklaration forventet ved læsning af XML-deklaration + standalone declaration expected while reading the XML declaration - + fri deklaration forventet ved læsning af XML-deklaration + error occurred while parsing document type definition der opstod fejl under fortolking af dokumenttypedefinition + letter is expected - + bogstav forventet + error occurred while parsing comment der opstod fejl under fortolking af kommentar + error occurred while parsing reference der opstod fejl under fortolking af reference + internal general entity reference not allowed in DTD - + intern generel entitetsreference ikke tilladt i DTD + external parsed general entity reference not allowed in attribute value - + Eksternt parset generel entitetsreference ikke tilladt i attributværdi + external parsed general entity reference not allowed in DTD - + Eksternt parset generel entitetsreference ikke tilladt i DTD + unparsed entity reference in wrong context ufortolket enhedsreference i forkert kontekst + recursive entities - + rekursive entiteter + error in the text declaration of an external entity fejl i tekstdeklaration pĂ¥ en ekstern enhed @@ -5271,412 +6505,485 @@ Vælg et andet filnavn. QXmlStream - + + Extra content at end of document. Ekstra indhold sidst i dokumentet. + Invalid entity value. Ugyldig enhedsværdi. + Invalid XML character. Ugyldigt XML-tegn. + Sequence ']]>' not allowed in content. Sekvens ']]>' ikke tilladt i indhold. + Namespace prefix '%1' not declared Navnerumspræfiks '%1' ikke deklareret + Attribute redefined. - + Attribut redefineret. + Unexpected character '%1' in public id literal. - + Uventet tegn '%1' i public id værdi. + Invalid XML version string. Ugyldigt XML-versionsstreng. + Unsupported XML version. XML-version understøttes ikke. + %1 is an invalid encoding name. - + %1 er et ugyldigt enkodningsnavn. + Encoding %1 is unsupported - + Enkodning %1 er ikke understøttet + Standalone accepts only yes or no. + Invalid attribute in XML declaration. - + Ugyldig attribut i XML-deklaration. + Premature end of document. - + Dokument sluttede for tidligt. + Invalid document. Ugyldigt dokument. + Expected Forventet + , but got ' , men fik ' + Unexpected ' Uventet ' + Expected character data. Forventet tegndata. + Recursive entity detected. - + Rekursiv entitet opdaget. + Start tag expected. Start-tag forventet. + XML declaration not at start of document. XML-deklaration ikke i starten af dokumentet. + NDATA in parameter entity declaration. - + NDATA i parameterentitetsdeklaration. + %1 is an invalid processing instruction name. - + %1 er et ugyldigt processing-instruction-navn. + Invalid processing instruction name. - + Ugyldigt processing-instruction-navn. + + + + Illegal namespace declaration. Ulovligt navnerumsdeklaration. - + Invalid XML name. Ugyldigt XML-navn. + Opening and ending tag mismatch. Ă…bner og afslutter tag-mismatch. + Reference to unparsed entity '%1'. Reference to ufortolket enhed '%1'. + + + Entity '%1' not declared. Enheden '%1' ikke deklareret. + Reference to external entity '%1' in attribute value. Reference til ekstern enhed '%1' i attributværdi. + Invalid character reference. Ugyldig tegnreference. + + Encountered incorrectly encoded content. - + Indhold med forkert enkodning læst. + The standalone pseudo attribute must appear after the encoding. - + Den frie pseudo-attribut skal optræde efter enkodningen. - + %1 is an invalid PUBLIC identifier. - + %1 er en ugyldig PUBLIC identifier. QtXmlPatterns - + An %1-attribute with value %2 has already been declared. - + En %1-attribut med værdi %2 er allerede erklæret. + An %1-attribute must have a valid %2 as value, which %3 isn't. - + En %1-attribut skal have en gyldig %2 som værdi, hvilket %3 ikke er. - + Network timeout. - + Netværk timeout. - + Element %1 can't be serialized because it appears outside the document element. - + Element %1 kan ikke serialiseres fordi det optræder udenfor dokument-elementet. - + Year %1 is invalid because it begins with %2. - + Ă…r %1 er ugyldigt da det begynder med %2. + Day %1 is outside the range %2..%3. - + Dag %1 er udenfor intervallet %2..%3. + Month %1 is outside the range %2..%3. - + MĂ¥ned %1 er udenfor intervallet %2..%3. + Overflow: Can't represent date %1. - + Overflow: Kan ikke repræsentere dato %1. + Day %1 is invalid for month %2. - + Dag %1 er ugyldig for mĂ¥net %2. + Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; - + Tidspunkt 24:%1:%2.%3 er ugyldigt. Timetal er 24, men minutter, sekunder og millisekunder er ikke alle 0; + Time %1:%2:%3.%4 is invalid. - + Tidspunkt %1:%2:%3.%4 er ugyldigt. + Overflow: Date can't be represented. - + Overflow: Dato kan ikke repræsenteres. + + At least one component must be present. - + Mindst en komponent skal være tilstede. + At least one time component must appear after the %1-delimiter. - + Mindst en tidskomponent skal optræde efter %1-skillemærket. - + No operand in an integer division, %1, can be %2. - + Ingen operand i en heltalsdivision, %1, kan være %2. + The first operand in an integer division, %1, cannot be infinity (%2). - + Den første operand i en heltalsdivision, %1, kan ikke være uendeligt (%2). + The second operand in a division, %1, cannot be zero (%2). - + Den anden operand i en division, %1, kan ikke være nul (%2). - + %1 is not a valid value of type %2. - + %1 er ikke en gyldig værdi af typen %2. - + When casting to %1 from %2, the source value cannot be %3. - + Ved cast til %1 fra %2, kan kildeværdien ikke være %3. - + Integer division (%1) by zero (%2) is undefined. - + Heltalsdivision (%1) med nul (%2) er udefineret. + Division (%1) by zero (%2) is undefined. - + Division (%1) med nul (%2) er udefineret. + Modulus division (%1) by zero (%2) is undefined. - + Modulusdivision (%1) med nul (%2) er udefineret. + + Dividing a value of type %1 by %2 (not-a-number) is not allowed. - + Division af værdi af typen %1 med %2 (ikke et tal) er ikke tilladt. + Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed. + Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed. - + A value of type %1 cannot have an Effective Boolean Value. - + Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values. - + Value %1 of type %2 exceeds maximum (%3). + Value %1 of type %2 is below minimum (%3). - + A value of type %1 must contain an even number of digits. The value %2 does not. + %1 is not valid as a value of type %2. - + Operator %1 cannot be used on type %2. + Operator %1 cannot be used on atomic values of type %2 and %3. - + The namespace URI in the name for a computed attribute cannot be %1. + The name for a computed attribute cannot have the namespace URI %1 with the local name %2. - + Type error in cast, expected %1, received %2. + When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed. - + No casting is possible with %1 as the target type. + It is not possible to cast from %1 to %2. + Casting to %1 is not possible because it is an abstract type, and can therefore never be instantiated. + It's not possible to cast the value %1 of type %2 to %3 + Failure when casting from %1 to %2: %3 - + A comment cannot contain %1 + A comment cannot end with a %1. - + No comparisons can be done involving the type %1. + Operator %1 is not available between atomic values of type %2 and %3. - + An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place. - + A library module cannot be evaluated directly. It must be imported from a main module. + No template by name %1 exists. - + A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type. + A positional predicate must evaluate to a single numeric value. - + The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, is %2 invalid. + %1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3. - + The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two. - + The data of a processing instruction cannot contain the string %1 - + No namespace binding exists for the prefix %1 - + No namespace binding exists for the prefix %1 in %2 - + + %1 is an invalid %2 - + %1 takes at most %n argument(s). %2 is therefore invalid. @@ -5684,6 +6991,7 @@ Vælg et andet filnavn. + %1 requires at least %n argument(s). %2 is therefore invalid. @@ -5691,613 +6999,731 @@ Vælg et andet filnavn. - + The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration. + The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. + The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5. - + %1 is not a valid XML 1.0 character. - + The first argument to %1 cannot be of type %2. - + If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same. - + %1 was called. - + %1 must be followed by %2 or %3, not at the end of the replacement string. + In the replacement string, %1 must be followed by at least one digit when not escaped. + In the replacement string, %1 can only be used to escape itself or %2, not %3 - + %1 matches newline characters + %1 and %2 match the start and end of a line. + Matches are case insensitive + Whitespace characters are removed, except when they appear in character classes + %1 is an invalid regular expression pattern: %2 + %1 is an invalid flag for regular expressions. Valid flags are: - + If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified. - + It will not be possible to retrieve %1. - + The root node of the second argument to function %1 must be a document node. %2 is not a document node. - + The default collection is undefined + %1 cannot be retrieved - + The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization). - + A zone offset must be in the range %1..%2 inclusive. %3 is out of range. + %1 is not a whole number of minutes. - + Required cardinality is %1; got cardinality %2. - + The item %1 did not match the required type %2. + + %1 is an unknown schema type. + Only one %1 declaration can occur in the query prolog. + The initialization of variable %1 depends on itself + No variable by name %1 exists - + The variable %1 is unused - + Version %1 is not supported. The supported XQuery version is 1.0. + The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2. + No function with signature %1 is available + + A default namespace declaration must occur before function, variable, and option declarations. + Namespace declarations must occur before function, variable, and option declarations. + Module imports must occur before function, variable, and option declarations. + It is not possible to redeclare prefix %1. + Prefix %1 is already declared in the prolog. + The name of an option must have a prefix. There is no default namespace for options. + The Schema Import feature is not supported, and therefore %1 declarations cannot occur. + The target namespace of a %1 cannot be empty. + The module import feature is not supported + No value is available for the external variable by name %1. + A construct was encountered which only is allowed in XQuery. + A template by name %1 has already been declared. + The keyword %1 cannot occur with any other mode name. + The value of attribute %1 must of type %2, which %3 isn't. + The prefix %1 can not be bound. By default, it is already bound to the namespace %2. + A variable by name %1 has already been declared. + A stylesheet function must have a prefixed name. + The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this) + The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases. + The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2 + A function already exists with the signature %1. + No external functions are supported. All supported functions can be used directly, without first declaring them as external + An argument by name %1 has already been declared. Every argument name must be unique. + When function %1 is used for matching inside a pattern, the argument must be a variable reference or a string literal. + In an XSL-T pattern, the first argument to function %1 must be a string literal, when used for matching. + In an XSL-T pattern, the first argument to function %1 must be a literal or a variable reference, when used for matching. + In an XSL-T pattern, function %1 cannot have a third argument. + In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. + In an XSL-T pattern, axis %1 cannot be used, only axis %2 or %3 can. + %1 is an invalid template mode name. + The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide. + The Schema Validation Feature is not supported. Hence, %1-expressions may not be used. + None of the pragma expressions are supported. Therefore, a fallback expression must be present + Each name of a template parameter must be unique; %1 is duplicated. + The %1-axis is unsupported in XQuery + %1 is not a valid name for a processing-instruction. + %1 is not a valid numeric literal. + No function by name %1 is available. + The namespace URI cannot be the empty string when binding to a prefix, %1. + %1 is an invalid namespace URI. + It is not possible to bind to the prefix %1 + Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared). + Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared). + Two namespace declaration attributes have the same name: %1. + The namespace URI must be a constant and cannot use enclosed expressions. + An attribute by name %1 has already appeared on this element. + A direct element constructor is not well-formed. %1 is ended with %2. + The name %1 does not refer to any schema type. + %1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works. + %1 is not an atomic type. Casting is only possible to atomic types. + + %1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported. + The name of an extension expression must be in a namespace. - + empty + zero or one + exactly one + one or more + zero or more - + Required type is %1, but %2 was found. + Promoting %1 to %2 may cause loss of precision. + The focus is undefined. - + It's not possible to add attributes after any other kind of node. + An attribute by name %1 has already been created. - + Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported. - + Attribute %1 can't be serialized because it appears at the top level. - + %1 is an unsupported encoding. + %1 contains octets which are disallowed in the requested encoding %2. + The codepoint %1, occurring in %2 using encoding %3, is an invalid XML character. - + Ambiguous rule match. - - In a namespace constructor, the value for a namespace value cannot be an empty string. + + In a namespace constructor, the value for a namespace cannot be an empty string. + The prefix must be a valid %1, which %2 is not. + The prefix %1 cannot be bound. + Only the prefix %1 can be bound to %2 and vice versa. - + Circularity detected - + The parameter %1 is required, but no corresponding %2 is supplied. + The parameter %1 is passed, but no corresponding %2 exists. - + The URI cannot have a fragment - + Element %1 is not allowed at this location. + Text nodes are not allowed at this location. + Parse error: %1 + The value of the XSL-T version attribute must be a value of type %1, which %2 isn't. + Running an XSL-T 1.0 stylesheet with a 2.0 processor. + Unknown XSL-T attribute %1. + Attribute %1 and %2 are mutually exclusive. + In a simplified stylesheet module, attribute %1 must be present. + If element %1 has no attribute %2, it cannot have attribute %3 or %4. + Element %1 must have at least one of the attributes %2 or %3. + At least one mode must be specified in the %1-attribute on element %2. - + Attribute %1 cannot appear on the element %2. Only the standard attributes can appear. + Attribute %1 cannot appear on the element %2. Only %3 is allowed, and the standard attributes. + Attribute %1 cannot appear on the element %2. Allowed is %3, %4, and the standard attributes. + Attribute %1 cannot appear on the element %2. Allowed is %3, and the standard attributes. + XSL-T attributes on XSL-T elements must be in the null namespace, not in the XSL-T namespace which %1 is. + The attribute %1 must appear on element %2. + The element with local name %1 does not exist in XSL-T. - + Element %1 must come last. + At least one %1-element must occur before %2. + Only one %1-element can appear. + At least one %1-element must occur inside %2. + When attribute %1 is present on %2, a sequence constructor cannot be used. + Element %1 must have either a %2-attribute or a sequence constructor. + When a parameter is required, a default value cannot be supplied through a %1-attribute or a sequence constructor. + Element %1 cannot have children. + Element %1 cannot have a sequence constructor. + + The attribute %1 cannot appear on %2, when it is a child of %3. + A parameter in a function cannot be declared to be a tunnel. + This processor is not Schema-aware and therefore %1 cannot be used. + Top level stylesheet elements must be in a non-null namespace, which %1 isn't. + The value for attribute %1 on element %2 must either be %3 or %4, not %5. + Attribute %1 cannot have the value %2. + The attribute %1 can only appear on the first %2 element. + At least one %1 element must appear as child of %2. @@ -6305,11 +7731,13 @@ Vælg et andet filnavn. VolumeSlider - + Muted + + Volume: %1% Lydstyrke: %1% diff --git a/translations/qt_help_da.ts b/translations/qt_help_da.ts index 0e4a362..73609a1 100644 --- a/translations/qt_help_da.ts +++ b/translations/qt_help_da.ts @@ -4,27 +4,27 @@ QCLuceneResultWidget - + Search Results Søgeresultater - + Note: Bemærk: - + The search results may not be complete since the documentation is still being indexed! Søgeresultaterne kan være ufuldstændige, fordi dokumentationen stadig indekseres! - + Your search did not match any documents. Søgningen matchede ikke nogen dokumenter. - + (The reason for this might be that the documentation is still being indexed.) (Ă…rsagen kan være, at dokumentationen stadig indekseres.) @@ -32,72 +32,78 @@ QHelpCollectionHandler - + The collection file is not set up yet! Hjælpesamlingen er ikke konfigureret endnu! - + + Cannot load sqlite database driver! + Kan ikke indlæse sqlite database-driver! + + + + Cannot open collection file: %1 Kan ikke Ă¥bne hjælpesamlingen: %1 - + Cannot create tables in file %1! Kan ikke oprette tabler i filen %1! - + The specified collection file already exists! Den angivne hjælpesamling findes allerede! - + Cannot create directory: %1 Kan ikke oprette kataloget: %1 - + Cannot copy collection file: %1 Kan ikke kopiere hjælpesamling: %1 - + Unknown filter! Ukendt filter! - + Cannot register filter %1! Kan ikke registrere filteret %1! - + Cannot open documentation file %1! Kan ikke Ă¥bne dokumentationsfilen %1! - + Invalid documentation file! Ugyldig dokumentationsfil! - + The namespace %1 was not registered! Navnerummet %1 blev ikke registreret! - + Namespace %1 already exists! Navnerummet %1 findes allerede! - + Cannot register namespace! Kan ikke registrere navnerummet! - + Cannot open database to optimize! Kan ikke Ă¥bne den database, der skal optimeres! @@ -105,15 +111,19 @@ QHelpDBReader - Cannot open DB! - Kan ikke Ă¥bne DB! + Kan ikke Ă¥bne DB! + + + + Cannot open database '%1' '%2': %3 + Kan ikke Ă¥bne database '%1' '%2': %3 QHelpEngineCore - + The specified namespace does not exist! Det angivne navnerum findes ikke! @@ -121,125 +131,135 @@ QHelpEngineCorePrivate - + + Cannot open documentation file %1: %2! + Kan ikke Ă¥bne dokumentationsfil %1: %2! + + Cannot open collection file %1! - Kan ikke Ă¥bne hjælpesamlingen %1! + Kan ikke Ă¥bne hjælpesamlingen %1! - Cannot open documentation file %1! - Kan ikke Ă¥bne dokumentationsfilen %1! + Kan ikke Ă¥bne dokumentationsfilen %1! QHelpGenerator - + Invalid help data! Ugyldigt hjælpedata! - + No output file name specified! Der er ikke anført et output-filnavn! - The file %1 already exists! - Filen %1 findes allerede! + Filen %1 findes allerede! - + Building up file structure... Bygger filstruktur... - Cannot open DB! - Kan ikke Ă¥bne DB! + Kan ikke Ă¥bne DB! + + + + The file %1 cannot be overwritten! + Filen %1 kan ikke overskrives! - + + Cannot open data base file %1! + Kan ikke Ă¥bne databasefil %1! + + + Cannot register namespace %1! Kan ikke registrere navnerummet %1! - + Insert custom filters... Indsæt brugerdefinerede filtre... - + Insert help data for filter section (%1 of %2)... Indsæt hjælpedata til filtersektion (%1 af %2)... - + Documentation successfully generated. Dokumentationen blev genereret. - + Some tables already exist! Nogle af tabellerne findes allerede! - + Cannot create tables! Kan ikke oprette tabeller! - + Cannot register virtual folder! Kan ikke registrere virtuel mappe! - + Insert files... Indsæt filer... - + The file %1 does not exist! Skipping it. Filen %1 findes ikke, og den springes over. - + Cannot open file %1! Skipping it. Kan ikke Ă¥bne filen %1, og den springes over. - Cannot insert file data into database! - Kan ikke indsætte fildata i databasen! + Kan ikke indsætte fildata i databasen! - + The filter %1 is already registered! Filtret %1 er allerede registreret! - + Cannot register filter %1! Kan ikke registrere filtret %1! - + Insert indices... Indsæt indeks... - + Insert contents... Indsæt indhold... - + Cannot insert contents! Kan ikke indsætte indhold! - + Cannot register contents! Kan ikke registrere indhold! @@ -247,42 +267,42 @@ QHelpSearchQueryWidget - + Search for: Søg efter: - + Search Søg - + Advanced search Avanceret søgning - + words <B>similar</B> to: ord <B>tilsvarende</B>: - + <B>without</B> the words: <B>uden</B> ordene: - + with <B>exact phrase</B>: med den <B>eksakte sætning</B>: - + with <B>all</B> of the words: med <B>alle</B> ordene: - + with <B>at least one</B> of the words: med <B>mindst Ă©t</B> af ordene: @@ -290,7 +310,7 @@ QHelpSearchResultWidget - + 0 - 0 of 0 Hits 0 - 0 af 0 Hits @@ -298,7 +318,7 @@ QHelpSearchResultWidgetPrivate - + %1 - %2 of %3 Hits %1 - %2 af %3 Hits @@ -306,47 +326,60 @@ QObject - + Untitled Ingen titel - Unknown token at line %1. - Ukendt symbol pĂ¥ linie %1. + Ukendt symbol pĂ¥ linie %1. - Unknown token at line %1. Expected "QtHelpProject"! - Ukendt symbol pĂ¥ linie %1. Forventet "QtHelpProject"! + Ukendt symbol pĂ¥ linie %1. Forventet "QtHelpProject"! + + + + Unknown token. + Ukendt token. + + + + Unknown token. Expected "QtHelpProject"! + Ukendt token. Forventede "QtHelpProject"! + + + + Error in line %1: %2 + Fejl i linie %1: %2 - + A virtual folder must not contain a '/' character! En virtuel mappe mĂ¥ ikke indholde tegnet '/'! - + A namespace must not contain a '/' character! Et navnerum mĂ¥ ikke indeholde tegnet '/'! - + Missing namespace in QtHelpProject. Navnerum i +++ mangler. - + Missing virtual folder in QtHelpProject Virtuel mappe i QtHelpProject mangler - + Missing attribute in keyword at line %1. Attribut i nøgleord pĂ¥ linie %1 mangler. - + The input file %1 could not be opened! Input-filen %1 kunne ikke Ă¥bnes! diff --git a/translations/translations.pri b/translations/translations.pri index efefa09..0c5c1ee 100644 --- a/translations/translations.pri +++ b/translations/translations.pri @@ -21,7 +21,7 @@ LRELEASE = $$fixPath($$QT_BUILD_TREE/bin/lrelease) ###### Qt Libraries -QT_TS = de fr zh_CN untranslated ar es iw ja_JP pl pt ru sk sv uk zh_TW +QT_TS = de fr zh_CN untranslated ar es iw ja_JP pl pt ru sk sv uk zh_TW da ts-qt.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ 3rdparty/phonon \ -- cgit v0.12 From 634954f1648a1ada74ba03f2eecec71e8bcba898 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 27 May 2009 16:41:53 +1000 Subject: Fix WinCE compile error not fixed by c666b88 You can't implicitly convert QLatin1Char to QString and thus neither to QFileInfo. Instead do the conversion the correct way, as illustrated by the code five lines above the line that broke. Reviewed-by: Lincoln Ramsay Reviewed-by: Andy Shaw --- src/corelib/io/qfsfileengine_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 82cde8b..0b87e2b 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1298,7 +1298,7 @@ QFileInfoList QFSFileEngine::drives() } return ret; #else - ret.append(QFileInfo(QLatin1Char('/'))); + ret.append(QString::fromLatin1("/")); return ret; #endif } -- cgit v0.12 From 5e14efa547ffac5890b008ad23e9ff0bc634a3e1 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 27 May 2009 09:38:32 +0200 Subject: Use GLInt and not uint because of Apple's old header swap --- src/opengl/qpixmapdata_gl_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 536f33d..7e06db9 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -116,7 +116,7 @@ private: int m_height; mutable QGLFramebufferObject *m_renderFbo; - mutable uint m_textureId; + mutable GLuint m_textureId; mutable QPaintEngine *m_engine; mutable QGLContext *m_ctx; mutable bool m_dirty; -- cgit v0.12 From 0ea19cf01e2381969a8b8ce8cdaffe9ce873d3a9 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 25 May 2009 22:47:06 +0200 Subject: Add a flag that ensure that a connection is made only one It is often desirable, when doing connection, to ensure that the same connection is only made once. This can be done with the Qt::UniqueConnection 'flag' Also documented the order the slot are called Reviewed-by: Brad --- doc/src/qnamespace.qdoc | 4 ++ doc/src/signalsandslots.qdoc | 14 ++++--- src/corelib/global/qnamespace.h | 3 +- src/corelib/kernel/qobject.cpp | 36 ++++++++++++----- tests/auto/qobject/tst_qobject.cpp | 81 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 119 insertions(+), 19 deletions(-) diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index fc4310b..069541f 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -528,6 +528,10 @@ Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection. + \value UniqueConnection Same as AutoConnection, but there will be a check that the signal is + not already connected to the same slot before connecting, otherwise, + the connection will fail. + \since 4.6 With queued connections, the parameters must be of types that are known to Qt's meta-object system, because Qt needs to copy the arguments to store them diff --git a/doc/src/signalsandslots.qdoc b/doc/src/signalsandslots.qdoc index 5432bd4..29c8215 100644 --- a/doc/src/signalsandslots.qdoc +++ b/doc/src/signalsandslots.qdoc @@ -178,9 +178,13 @@ looping in the case of cyclic connections (e.g., if \c{b.valueChanged()} were connected to \c{a.setValue()}). - A signal is emitted for every connection you make; if you - duplicate a connection, two signals will be emitted. You can - always break a connection using QObject::disconnect(). + By default, for every connection you make, a signal is emitted; + two signals are emitted for duplicate connections. You can break + all of these connections with a single disconnect() call. + If you pass the Qt::UniqueConnection \a type, the connection will only + be made if it is not a duplicate. If there is already a duplicate + (exact same signal to the exact same slot on the same objects), + the connection will fail and connect will return false This example illustrates that objects can work together without needing to know any information about each other. To enable this, the objects only @@ -218,8 +222,8 @@ will continue immediately, and the slots will be executed later. If several slots are connected to one signal, the slots will be - executed one after the other, in an arbitrary order, when the signal - is emitted. + executed one after the other, in the order they have been connected, + when the signal is emitted. Signals are automatically generated by the \l moc and must not be implemented in the \c .cpp file. They can never have return types diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 3367581..9e53d89 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1327,7 +1327,8 @@ public: DirectConnection, QueuedConnection, AutoCompatConnection, - BlockingQueuedConnection + BlockingQueuedConnection, + UniqueConnection = 0x80 }; enum ShortcutContext { diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 65d81f1..be622d9 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -301,7 +301,6 @@ void QObjectPrivate::addConnection(int signal, Connection *c) ConnectionList &connectionList = (*connectionLists)[signal]; connectionList.append(c); - cleanConnectionLists(); } @@ -2377,7 +2376,8 @@ int QObject::receivers(const char *signal) const can be connected to one slot. If a signal is connected to several slots, the slots are activated - in an arbitrary order when the signal is emitted. + in the same order as the order the connection was made, when the + signal is emitted. The function returns true if it successfully connects the signal to the slot. It will return false if it cannot create the @@ -2385,9 +2385,13 @@ int QObject::receivers(const char *signal) const existence of either \a signal or \a method, or if their signatures aren't compatible. - For every connection you make, a signal is emitted; two signals are emitted - for duplicate connections. You can break all of these connections with a - single disconnect() call. + By default, a signal is emitted for every connection you make; + two signals are emitted for duplicate connections. You can break + all of these connections with a single disconnect() call. + If you pass the Qt::UniqueConnection \a type, the connection will only + be made if it is not a duplicate. If there is already a duplicate + (exact same signal to the exact same slot on the same objects), + the connection will fail and connect will return false The optional \a type parameter describes the type of connection to establish. In particular, it determines whether a particular @@ -2520,7 +2524,8 @@ bool QObject::connect(const QObject *sender, const char *signal, } } #endif - QMetaObject::connect(sender, signal_index, receiver, method_index, type, types); + if (!QMetaObject::connect(sender, signal_index, receiver, method_index, type, types)) + return false; const_cast(sender)->connectNotify(signal - 1); return true; } @@ -2771,6 +2776,22 @@ bool QMetaObject::connect(const QObject *sender, int signal_index, QObject *s = const_cast(sender); QObject *r = const_cast(receiver); + QOrderedMutexLocker locker(signalSlotLock(sender), + signalSlotLock(receiver)); + + if (type & Qt::UniqueConnection) { + QObjectConnectionListVector *connectionLists = s->d_func()->connectionLists; + if (connectionLists && connectionLists->count() > signal_index) { + QObjectPrivate::ConnectionList &connectionList = (*connectionLists)[signal_index]; + for (int i = 0; i < connectionList.count(); ++i) { + QObjectPrivate::Connection *c2 = connectionList.at(i); + if (c2->receiver == receiver && c2->method == method_index) + return false; + } + } + type &= Qt::UniqueConnection - 1; + } + QObjectPrivate::Connection *c = new QObjectPrivate::Connection; c->sender = s; c->receiver = r; @@ -2778,9 +2799,6 @@ bool QMetaObject::connect(const QObject *sender, int signal_index, c->connectionType = type; c->argumentTypes = types; - QOrderedMutexLocker locker(signalSlotLock(sender), - signalSlotLock(receiver)); - s->d_func()->addConnection(signal_index, c); r->d_func()->senders.append(c); diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index fb46073..399d021 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -116,6 +116,7 @@ private slots: void dumpObjectInfo(); void connectToSender(); void qobjectConstCast(); + void uniqConnection(); protected: }; @@ -204,12 +205,20 @@ public: sequence_slot3 = 0; sequence_slot2 = 0; sequence_slot1 = 0; + count_slot1 = 0; + count_slot2 = 0; + count_slot3 = 0; + count_slot4 = 0; } int sequence_slot1; int sequence_slot2; int sequence_slot3; int sequence_slot4; + int count_slot1; + int count_slot2; + int count_slot3; + int count_slot4; bool called(int slot) { switch (slot) { @@ -224,10 +233,10 @@ public: static int sequence; public slots: - void slot1() { sequence_slot1 = ++sequence; } - void slot2() { sequence_slot2 = ++sequence; } - void slot3() { sequence_slot3 = ++sequence; } - void slot4() { sequence_slot4 = ++sequence; } + void slot1() { sequence_slot1 = ++sequence; count_slot1++; } + void slot2() { sequence_slot2 = ++sequence; count_slot2++; } + void slot3() { sequence_slot3 = ++sequence; count_slot3++; } + void slot4() { sequence_slot4 = ++sequence; count_slot4++; } }; @@ -2783,5 +2792,69 @@ void tst_QObject::qobjectConstCast() QVERIFY(qobject_cast(cptr)); } +void tst_QObject::uniqConnection() +{ + SenderObject *s = new SenderObject; + ReceiverObject *r1 = new ReceiverObject; + ReceiverObject *r2 = new ReceiverObject; + r1->reset(); + r2->reset(); + ReceiverObject::sequence = 0; + + QVERIFY( connect( s, SIGNAL( signal1() ), r1, SLOT( slot1() ) , Qt::UniqueConnection) ); + QVERIFY( connect( s, SIGNAL( signal1() ), r2, SLOT( slot1() ) , Qt::UniqueConnection) ); + QVERIFY( connect( s, SIGNAL( signal1() ), r1, SLOT( slot3() ) , Qt::UniqueConnection) ); + QVERIFY( connect( s, SIGNAL( signal3() ), r1, SLOT( slot3() ) , Qt::UniqueConnection) ); + + s->emitSignal1(); + s->emitSignal2(); + s->emitSignal3(); + s->emitSignal4(); + + QCOMPARE( r1->count_slot1, 1 ); + QCOMPARE( r1->count_slot2, 0 ); + QCOMPARE( r1->count_slot3, 2 ); + QCOMPARE( r1->count_slot4, 0 ); + QCOMPARE( r2->count_slot1, 1 ); + QCOMPARE( r2->count_slot2, 0 ); + QCOMPARE( r2->count_slot3, 0 ); + QCOMPARE( r2->count_slot4, 0 ); + QCOMPARE( r1->sequence_slot1, 1 ); + QCOMPARE( r2->sequence_slot1, 2 ); + QCOMPARE( r1->sequence_slot3, 4 ); + + r1->reset(); + r2->reset(); + ReceiverObject::sequence = 0; + + QVERIFY( connect( s, SIGNAL( signal4() ), r1, SLOT( slot4() ) , Qt::UniqueConnection) ); + QVERIFY( connect( s, SIGNAL( signal4() ), r2, SLOT( slot4() ) , Qt::UniqueConnection) ); + QVERIFY(!connect( s, SIGNAL( signal4() ), r2, SLOT( slot4() ) , Qt::UniqueConnection) ); + QVERIFY( connect( s, SIGNAL( signal1() ), r2, SLOT( slot4() ) , Qt::UniqueConnection) ); + QVERIFY(!connect( s, SIGNAL( signal4() ), r1, SLOT( slot4() ) , Qt::UniqueConnection) ); + + s->emitSignal4(); + QCOMPARE( r1->count_slot4, 1 ); + QCOMPARE( r2->count_slot4, 1 ); + QCOMPARE( r1->sequence_slot4, 1 ); + QCOMPARE( r2->sequence_slot4, 2 ); + + r1->reset(); + r2->reset(); + ReceiverObject::sequence = 0; + + connect( s, SIGNAL( signal4() ), r1, SLOT( slot4() ) ); + + s->emitSignal4(); + QCOMPARE( r1->count_slot4, 2 ); + QCOMPARE( r2->count_slot4, 1 ); + QCOMPARE( r1->sequence_slot4, 3 ); + QCOMPARE( r2->sequence_slot4, 2 ); + + delete s; + delete r1; + delete r2; +} + QTEST_MAIN(tst_QObject) #include "tst_qobject.moc" -- cgit v0.12 From 00ffd16d367a19f958149b3b4ec5f5c5e6b71f9b Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 27 May 2009 09:56:16 +0200 Subject: Do not use the locale in QDoubleSpinBoxPrivate::round We had a report from a customer saying this breaks if the decimal separator is the same as the group separator. This is not really something we want to support, but because this fix is easy and cleanup the code I decided to fix it. Reviewed-by: Thierry Task-number: 253962 --- src/gui/widgets/qspinbox.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp index b7426f0..f12946c 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -1254,9 +1254,7 @@ QVariant QDoubleSpinBoxPrivate::valueFromText(const QString &f) const double QDoubleSpinBoxPrivate::round(double value) const { - Q_Q(const QDoubleSpinBox); - const QString strDbl = q->locale().toString(value, 'f', decimals); - return q->locale().toDouble(strDbl); + return QString::number(value, 'f', decimals).toDouble(); } -- cgit v0.12 From 0bcfa7aa496d460c72862369662560c49eb55f17 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 27 May 2009 11:48:20 +0200 Subject: small refactor to change the interpolator at the same time as the current interval in the variant animations --- src/corelib/animation/qpropertyanimation.cpp | 11 ++++--- src/corelib/animation/qpropertyanimation_p.h | 2 +- src/corelib/animation/qvariantanimation.cpp | 43 +++++++++++++++++++--------- src/corelib/animation/qvariantanimation_p.h | 18 ++++-------- 4 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index 9a17049..47361a5 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -110,17 +110,16 @@ void QPropertyAnimationPrivate::updateMetaProperty() if (!target || propertyName.isEmpty()) return; - if (hasMetaProperty == 0 && !property.isValid()) { + if (!hasMetaProperty && !property.isValid()) { const QMetaObject *mo = target->metaObject(); propertyIndex = mo->indexOfProperty(propertyName); if (propertyIndex != -1) { - hasMetaProperty = 1; + hasMetaProperty = true; property = mo->property(propertyIndex); propertyType = property.userType(); } else { if (!target->dynamicPropertyNames().contains(propertyName)) qWarning("QPropertyAnimation: you're trying to animate a non-existing property %s of your QObject", propertyName.constData()); - hasMetaProperty = 2; } } @@ -133,7 +132,7 @@ void QPropertyAnimationPrivate::updateProperty(const QVariant &newValue) if (!target || state == QAbstractAnimation::Stopped) return; - if (hasMetaProperty == 1) { + if (hasMetaProperty) { if (newValue.userType() == propertyType) { //no conversion is needed, we directly call the QObject::qt_metacall void *data = const_cast(newValue.constData()); @@ -216,7 +215,7 @@ void QPropertyAnimation::setTargetObject(QObject *target) connect(target, SIGNAL(destroyed()), SLOT(_q_targetDestroyed())); d->target = target; - d->hasMetaProperty = 0; + d->hasMetaProperty = false; d->updateMetaProperty(); } @@ -242,7 +241,7 @@ void QPropertyAnimation::setPropertyName(const QByteArray &propertyName) } d->propertyName = propertyName; - d->hasMetaProperty = 0; + d->hasMetaProperty = false; d->updateMetaProperty(); } diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h index b51d039..a4387dd 100644 --- a/src/corelib/animation/qpropertyanimation_p.h +++ b/src/corelib/animation/qpropertyanimation_p.h @@ -78,7 +78,7 @@ public: int propertyType; int propertyIndex; - int hasMetaProperty; + bool hasMetaProperty; QByteArray propertyName; void updateProperty(const QVariant &); void updateMetaProperty(); diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 239add9..e973ec5 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -144,6 +144,11 @@ static bool animationValueLessThan(const QVariantAnimation::KeyValue &p1, const return p1.first < p2.first; } +static QVariant defaultInterpolator(const void *, const void *, qreal) +{ + return QVariant(); +} + template<> Q_INLINE_TEMPLATE QRect _q_interpolate(const QRect &f, const QRect &t, qreal progress) { QRect ret; @@ -174,6 +179,13 @@ template<> Q_INLINE_TEMPLATE QLineF _q_interpolate(const QLineF &f, const QLineF return QLineF( _q_interpolate(f.p1(), t.p1(), progress), _q_interpolate(f.p2(), t.p2(), progress)); } +QVariantAnimationPrivate::QVariantAnimationPrivate() : duration(250), hasStartValue(false), + interpolator(&defaultInterpolator), + changedSignalMask(1 << QVariantAnimation::staticMetaObject.indexOfSignal("valueChanged(QVariant)")) +{ + //we keep the mask so that we emit valueChanged only when needed (for performance reasons) +} + void QVariantAnimationPrivate::convertValues(int t) { //this ensures that all the keyValues are of type t @@ -186,7 +198,20 @@ void QVariantAnimationPrivate::convertValues(int t) currentInterval.end.second.convert(static_cast(t)); //... and the interpolator - interpolator = 0; + updateInterpolator(); +} + +void QVariantAnimationPrivate::updateInterpolator() +{ + int type = currentInterval.start.second.userType(); + if (type == currentInterval.end.second.userType()) + interpolator = getInterpolator(type); + else + interpolator = 0; + + //we make sure that the interpolator is always set to something + if (!interpolator) + interpolator = &defaultInterpolator; } /*! @@ -224,6 +249,7 @@ void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/) // update all the values of the currentInterval currentInterval.start = *itStart; currentInterval.end = *itEnd; + updateInterpolator(); } } setCurrentValueForProgress(progress); @@ -295,7 +321,6 @@ void QVariantAnimationPrivate::setDefaultStartValue(const QVariant &value) */ QVariantAnimation::QVariantAnimation(QObject *parent) : QAbstractAnimation(*new QVariantAnimationPrivate, parent) { - d_func()->init(); } /*! @@ -303,7 +328,6 @@ QVariantAnimation::QVariantAnimation(QObject *parent) : QAbstractAnimation(*new */ QVariantAnimation::QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent) : QAbstractAnimation(dd, parent) { - d_func()->init(); } /*! @@ -629,15 +653,7 @@ void QVariantAnimation::updateState(QAbstractAnimation::State oldState, */ QVariant QVariantAnimation::interpolated(const QVariant &from, const QVariant &to, qreal progress) const { - Q_D(const QVariantAnimation); - if (d->interpolator == 0) { - if (from.userType() == to.userType()) - d->interpolator = QVariantAnimationPrivate::getInterpolator(from.userType()); - if (d->interpolator == 0) //no interpolator found - return QVariant(); - } - - return d->interpolator(from.constData(), to.constData(), progress); + return d_func()->interpolator(from.constData(), to.constData(), progress); } /*! @@ -645,9 +661,8 @@ QVariant QVariantAnimation::interpolated(const QVariant &from, const QVariant &t */ void QVariantAnimation::updateCurrentTime(int msecs) { - Q_D(QVariantAnimation); Q_UNUSED(msecs); - d->recalculateCurrentInterval(); + d_func()->recalculateCurrentInterval(); } QT_END_NAMESPACE diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h index 0d296db..2c559cf 100644 --- a/src/corelib/animation/qvariantanimation_p.h +++ b/src/corelib/animation/qvariantanimation_p.h @@ -67,17 +67,7 @@ class QVariantAnimationPrivate : public QAbstractAnimationPrivate Q_DECLARE_PUBLIC(QVariantAnimation) public: - QVariantAnimationPrivate() : duration(250), hasStartValue(false) - { - } - - void init() - { - //we keep the mask so that we emit valueChanged only when needed (for performance reasons) - changedSignalMask = (1 << q_func()->metaObject()->indexOfSignal("valueChanged(QVariant)")); - currentInterval.start.first = currentInterval.end.first = 2; //will force the initial refresh - interpolator = 0; - } + QVariantAnimationPrivate(); static QVariantAnimationPrivate *get(QVariantAnimation *q) { @@ -100,9 +90,9 @@ public: QVariantAnimation::KeyValue start, end; } currentInterval; - mutable QVariantAnimation::Interpolator interpolator; + QVariantAnimation::Interpolator interpolator; - quint32 changedSignalMask; + const quint32 changedSignalMask; void setCurrentValueForProgress(const qreal progress); void recalculateCurrentInterval(bool force=false); @@ -110,6 +100,8 @@ public: QVariant valueAt(qreal step) const; void convertValues(int t); + void updateInterpolator(); + static QVariantAnimation::Interpolator getInterpolator(int interpolationType); }; -- cgit v0.12 From 80bc757b56953065fafeffe6c4b8fb6fbca287ac Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 27 May 2009 10:30:07 +0200 Subject: Avoid deep copies of pixmaps when using cache in QGraphicsView. When we have already a pixmap of an item in the cache, we should remove the entry from the cache otherwise when we will repaint/modify the copy of the pixmap (the copy of the cache) then we will trigger a deep copy ; this is because both entries in the cache and our copy share the same data and if you modify one of them a copy is triggered. I have added a benchmark as well to test that. Reviewed-by:bnilsen Reviewed-by:andreas --- src/gui/graphicsview/qgraphicsscene.cpp | 28 +++--- .../benchmarks/qgraphicsview/images/wine-big.jpeg | Bin 0 -> 12249 bytes tests/benchmarks/qgraphicsview/qgraphicsview.qrc | 1 + .../benchmarks/qgraphicsview/tst_qgraphicsview.cpp | 102 +++++++++++++++++++++ 4 files changed, 118 insertions(+), 13 deletions(-) create mode 100644 tests/benchmarks/qgraphicsview/images/wine-big.jpeg diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 126ea5b..1fc4567 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4784,6 +4784,12 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte // Redraw any newly exposed areas. if (itemCache->allExposed || !itemCache->exposed.isEmpty()) { + + //We know that we will modify the pixmap, removing it from the cache + //will detach the one we have and avoid a deep copy + if (pixmapFound) + QPixmapCache::remove(pixmapKey); + // Fit the item's bounding rect into the pixmap's coordinates. QTransform itemToPixmap; if (fixedCacheSize) { @@ -4812,12 +4818,8 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte _q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(), &cacheOption, painterStateProtection); - if (!pixmapFound) { - // insert this pixmap into the cache. - itemCache->key = QPixmapCache::insert(pix); - } else { - QPixmapCache::replace(pixmapKey, pix); - } + // insert this pixmap into the cache. + itemCache->key = QPixmapCache::insert(pix); // Reset expose data. itemCache->allExposed = false; @@ -4944,6 +4946,11 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte // Check for newly invalidated areas. if (itemCache->allExposed || !itemCache->exposed.isEmpty() || !scrollExposure.isEmpty()) { + //We know that we will modify the pixmap, removing it from the cache + //will detach the one we have and avoid a deep copy + if (pixmapFound) + QPixmapCache::remove(pixmapKey); + // Construct an item-to-pixmap transform. QPointF p = deviceRect.topLeft(); QTransform itemToPixmap = painter->worldTransform(); @@ -4984,13 +4991,8 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte } if (pixModified) { - if (!pixmapFound) { - // Insert this pixmap into the cache. - deviceData->key = QPixmapCache::insert(pix); - } else { - //otherwise we replace the pixmap in the cache - QPixmapCache::replace(pixmapKey, pix); - } + // Insert this pixmap into the cache. + deviceData->key = QPixmapCache::insert(pix); } // Redraw the exposed area using an untransformed painter. This diff --git a/tests/benchmarks/qgraphicsview/images/wine-big.jpeg b/tests/benchmarks/qgraphicsview/images/wine-big.jpeg new file mode 100644 index 0000000..9900a50 Binary files /dev/null and b/tests/benchmarks/qgraphicsview/images/wine-big.jpeg differ diff --git a/tests/benchmarks/qgraphicsview/qgraphicsview.qrc b/tests/benchmarks/qgraphicsview/qgraphicsview.qrc index 5e80029..3681648 100644 --- a/tests/benchmarks/qgraphicsview/qgraphicsview.qrc +++ b/tests/benchmarks/qgraphicsview/qgraphicsview.qrc @@ -2,6 +2,7 @@ images/designer.png images/wine.jpeg + images/wine-big.jpeg random.data diff --git a/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp b/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp index a06e033..570f744 100644 --- a/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/benchmarks/qgraphicsview/tst_qgraphicsview.cpp @@ -124,6 +124,8 @@ private slots: void textRiver(); void moveItemCache_data(); void moveItemCache(); + void paintItemCache_data(); + void paintItemCache(); }; tst_QGraphicsView::tst_QGraphicsView() @@ -796,5 +798,105 @@ void tst_QGraphicsView::moveItemCache() } } +class UpdatedPixmapCacheItem : public QGraphicsPixmapItem +{ +public: + UpdatedPixmapCacheItem(bool partial, QGraphicsItem *parent = 0) + : QGraphicsPixmapItem(parent), partial(partial) + { + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) + { + QGraphicsPixmapItem::paint(painter,option,widget); + } +protected: + void advance(int i) + { + if (partial) + update(QRectF(boundingRect().center().x(), boundingRect().center().x(), 30, 30)); + else + update(); + } + +private: + bool partial; +}; + +void tst_QGraphicsView::paintItemCache_data() +{ + QTest::addColumn("updatePartial"); + QTest::addColumn("rotation"); + QTest::addColumn("cacheMode"); + QTest::newRow("Partial Update : ItemCoordinate Cache") << true << false << (int)QGraphicsItem::ItemCoordinateCache; + QTest::newRow("Partial Update : DeviceCoordinate Cache") << true << false << (int)QGraphicsItem::DeviceCoordinateCache; + QTest::newRow("Partial Update : No Cache") << true << false << (int)QGraphicsItem::NoCache; + QTest::newRow("Full Update : ItemCoordinate Cache") << false << false << (int)QGraphicsItem::ItemCoordinateCache; + QTest::newRow("Full Update : DeviceCoordinate Cache") << false << false << (int)QGraphicsItem::DeviceCoordinateCache; + QTest::newRow("Full Update : No Cache") << false << false << (int)QGraphicsItem::NoCache; + QTest::newRow("Partial Update : ItemCoordinate Cache item rotated") << true << true << (int)QGraphicsItem::ItemCoordinateCache; + QTest::newRow("Partial Update : DeviceCoordinate Cache item rotated") << true << true << (int)QGraphicsItem::DeviceCoordinateCache; + QTest::newRow("Partial Update : No Cache item rotated") << true << true << (int)QGraphicsItem::NoCache; + QTest::newRow("Full Update : ItemCoordinate Cache item rotated") << false << true << (int)QGraphicsItem::ItemCoordinateCache; + QTest::newRow("Full Update : DeviceCoordinate Cache item rotated") << false << true << (int)QGraphicsItem::DeviceCoordinateCache; + QTest::newRow("Full Update : No Cache item rotated") << false << true <<(int)QGraphicsItem::NoCache; +} + +void tst_QGraphicsView::paintItemCache() +{ + QFETCH(bool, updatePartial); + QFETCH(bool, rotation); + QFETCH(int, cacheMode); + + QGraphicsScene scene(0, 0, 300, 300); + + CountPaintEventView view(&scene); + view.resize(600, 600); + view.setFrameStyle(0); + view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + view.show(); + + QPixmap pix(":/images/wine.jpeg"); + QVERIFY(!pix.isNull()); + + QList items; + QFile file(":/random.data"); + QVERIFY(file.open(QIODevice::ReadOnly)); + QDataStream str(&file); + UpdatedPixmapCacheItem *item = new UpdatedPixmapCacheItem(updatePartial); + item->setPixmap(pix); + item->setCacheMode((QGraphicsItem::CacheMode)cacheMode); + if (rotation) + item->setTransform(QTransform().rotate(45)); + item->setPos(-100, -100); + scene.addItem(item); + + QPixmap pix2(":/images/wine-big.jpeg"); + item = new UpdatedPixmapCacheItem(updatePartial); + item->setPixmap(pix2); + item->setCacheMode((QGraphicsItem::CacheMode)cacheMode); + if (rotation) + item->setTransform(QTransform().rotate(45)); + item->setPos(0, 0); + scene.addItem(item); + + view.count = 0; + + QBENCHMARK { +#ifdef CALLGRIND_DEBUG + CALLGRIND_START_INSTRUMENTATION +#endif + for (int i = 0; i < 50; ++i) { + scene.advance(); + while (view.count < (i+1)) + qApp->processEvents(); + } +#ifdef CALLGRIND_DEBUG + CALLGRIND_STOP_INSTRUMENTATION +#endif + } +} + QTEST_MAIN(tst_QGraphicsView) #include "tst_qgraphicsview.moc" -- cgit v0.12 From 2c1b11f2192fd48da01a1093a7cb4a848de43c8a Mon Sep 17 00:00:00 2001 From: Trond Kjernaasen Date: Wed, 27 May 2009 11:11:57 +0200 Subject: Fixed aliasing pointer corruption in QDataStream. Use a union instead of an unsafe cast when swapping the bytes in the QDataStream streaming operators. The old seems to cause problems with Link Time Code Generation optimizations with the MSVC compilers. Task-number: 247708 Reviewed-by: Samuel Reviewed-by: Thiago BT: yes --- src/corelib/io/qdatastream.cpp | 92 +++++++++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 15 deletions(-) diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index b203899..e324ffe 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -622,11 +622,16 @@ QDataStream &QDataStream::operator>>(qint16 &i) setStatus(ReadPastEnd); } } else { - register uchar *p = (uchar *)(&i); + union { + qint16 val1; + char val2[2]; + } x; + char *p = x.val2; char b[2]; if (dev->read(b, 2) == 2) { *p++ = b[1]; *p = b[0]; + i = x.val1; } else { setStatus(ReadPastEnd); } @@ -660,13 +665,18 @@ QDataStream &QDataStream::operator>>(qint32 &i) setStatus(ReadPastEnd); } } else { // swap bytes - uchar *p = (uchar *)(&i); + union { + qint32 val1; + char val2[4]; + } x; + char *p = x.val2; char b[4]; if (dev->read(b, 4) == 4) { *p++ = b[3]; *p++ = b[2]; *p++ = b[1]; *p = b[0]; + i = x.val1; } else { setStatus(ReadPastEnd); } @@ -703,7 +713,12 @@ QDataStream &QDataStream::operator>>(qint64 &i) setStatus(ReadPastEnd); } } else { // swap bytes - uchar *p = (uchar *)(&i); + union { + qint64 val1; + char val2[8]; + } x; + + char *p = x.val2; char b[8]; if (dev->read(b, 8) == 8) { *p++ = b[7]; @@ -714,6 +729,7 @@ QDataStream &QDataStream::operator>>(qint64 &i) *p++ = b[2]; *p++ = b[1]; *p = b[0]; + i = x.val1; } else { setStatus(ReadPastEnd); } @@ -751,13 +767,19 @@ QDataStream &QDataStream::operator>>(float &f) setStatus(ReadPastEnd); } } else { // swap bytes - uchar *p = (uchar *)(&f); + union { + float val1; + char val2[4]; + } x; + + char *p = x.val2; char b[4]; if (dev->read(b, 4) == 4) { *p++ = b[3]; *p++ = b[2]; *p++ = b[1]; *p = b[0]; + f = x.val1; } else { setStatus(ReadPastEnd); } @@ -788,7 +810,11 @@ QDataStream &QDataStream::operator>>(double &f) setStatus(ReadPastEnd); } } else { // swap bytes - register uchar *p = (uchar *)(&f); + union { + double val1; + char val2[8]; + } x; + char *p = x.val2; char b[8]; if (dev->read(b, 8) == 8) { *p++ = b[7]; @@ -799,13 +825,18 @@ QDataStream &QDataStream::operator>>(double &f) *p++ = b[2]; *p++ = b[1]; *p = b[0]; + f = x.val1; } else { setStatus(ReadPastEnd); } } #else //non-standard floating point format - register uchar *p = (uchar *)(&f); + union { + double val1; + char val2[8]; + } x; + char *p = x.val2; char b[8]; if (dev->read(b, 8) == 8) { if (noswap) { @@ -827,6 +858,7 @@ QDataStream &QDataStream::operator>>(double &f) *p++ = b[Q_DF(1)]; *p = b[Q_DF(0)]; } + f = x.val1; } else { setStatus(ReadPastEnd); } @@ -970,7 +1002,12 @@ QDataStream &QDataStream::operator<<(qint16 i) if (noswap) { dev->write((char *)&i, sizeof(qint16)); } else { // swap bytes - register uchar *p = (uchar *)(&i); + union { + qint16 val1; + char val2[2]; + } x; + x.val1 = i; + char *p = x.val2; char b[2]; b[1] = *p++; b[0] = *p; @@ -992,7 +1029,12 @@ QDataStream &QDataStream::operator<<(qint32 i) if (noswap) { dev->write((char *)&i, sizeof(qint32)); } else { // swap bytes - register uchar *p = (uchar *)(&i); + union { + qint32 val1; + char val2[4]; + } x; + x.val1 = i; + char *p = x.val2; char b[4]; b[3] = *p++; b[2] = *p++; @@ -1022,13 +1064,18 @@ QDataStream &QDataStream::operator<<(qint64 i) { CHECK_STREAM_PRECOND(*this) if (version() < 6) { - quint32 i1 = i & 0xffffffff; - quint32 i2 = i >> 32; - *this << i2 << i1; + quint32 i1 = i & 0xffffffff; + quint32 i2 = i >> 32; + *this << i2 << i1; } else if (noswap) { // no conversion needed dev->write((char *)&i, sizeof(qint64)); } else { // swap bytes - register uchar *p = (uchar *)(&i); + union { + qint64 val1; + char val2[8]; + } x; + x.val1 = i; + char *p = x.val2; char b[8]; b[7] = *p++; b[6] = *p++; @@ -1077,7 +1124,12 @@ QDataStream &QDataStream::operator<<(float f) if (noswap) { // no conversion needed dev->write((char *)&g, sizeof(float)); } else { // swap bytes - register uchar *p = (uchar *)(&g); + union { + float val1; + char val2[4]; + } x; + x.val1 = f; + char *p = x.val2; char b[4]; b[3] = *p++; b[2] = *p++; @@ -1103,7 +1155,12 @@ QDataStream &QDataStream::operator<<(double f) if (noswap) { dev->write((char *)&f, sizeof(double)); } else { - register uchar *p = (uchar *)(&f); + union { + double val1; + char val2[8]; + } x; + x.val1 = f; + char *p = x.val2; char b[8]; b[7] = *p++; b[6] = *p++; @@ -1116,7 +1173,12 @@ QDataStream &QDataStream::operator<<(double f) dev->write(b, 8); } #else - register uchar *p = (uchar *)(&f); + union { + double val1; + char val2[8]; + } x; + x.val1 = f; + char *p = x.val2; char b[8]; if (noswap) { b[Q_DF(0)] = *p++; -- cgit v0.12 From cfdfdf079c4a2095c588dd8af8403c74d2cfa37a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 27 May 2009 09:44:14 +0200 Subject: Optimized QRasterPixmapData::metric. Avoid needless DPI calculations when not needed, and simplify the DPI calculations to the point where most of the operations disappear. Also avoid calling QImage::metric() so that we don't need to go through two switch statements and an extra function call just to get the width of a pixmap. Reviewed-by: Trond --- src/gui/image/qpixmap_raster.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index b5556cd..29e4f3f 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -322,25 +322,36 @@ extern int qt_defaultDpiY(); int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const { + QImageData *d = image.d; + if (!d) + return 0; + // override the image dpi with the screen dpi when rendering to a pixmap - const int dpmX = qRound(qt_defaultDpiX() * 100 / qreal(2.54)); - const int dpmY = qRound(qt_defaultDpiY() * 100 / qreal(2.54)); switch (metric) { + case QPaintDevice::PdmWidth: + return d->width; + case QPaintDevice::PdmHeight: + return d->height; case QPaintDevice::PdmWidthMM: - return qRound(image.width() * 1000 / dpmX); + return qRound(d->width * 25.4 / qt_defaultDpiX()); case QPaintDevice::PdmHeightMM: - return qRound(image.height() * 1000 / dpmY); - case QPaintDevice::PdmDpiX: - return qRound(dpmX * qreal(0.0254)); - case QPaintDevice::PdmDpiY: - return qRound(dpmY * qreal(0.0254)); + return qRound(d->width * 25.4 / qt_defaultDpiY()); + case QPaintDevice::PdmNumColors: + return d->colortable.size(); + case QPaintDevice::PdmDepth: + return d->depth; + case QPaintDevice::PdmDpiX: // fall-through case QPaintDevice::PdmPhysicalDpiX: - return qRound(dpmX * qreal(0.0254)); + return qt_defaultDpiX(); + case QPaintDevice::PdmDpiY: // fall-through case QPaintDevice::PdmPhysicalDpiY: - return qRound(dpmY * qreal(0.0254)); + return qt_defaultDpiY(); default: - return image.metric(metric); + qWarning("QRasterPixmapData::metric(): Unhandled metric type %d", metric); + break; } + + return 0; } QImage* QRasterPixmapData::buffer() -- cgit v0.12 From 15c8f565973592c9929cdd6fc83d61641aa63afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 25 May 2009 14:56:27 +0200 Subject: Fixed bugs in GL2 paint engine when several engines are active. Make sure makeCurrent() on a window surface unbinds any active FBO, and simplify ensureActive() code in GL2 paint engine a bit. We don't need the last_engine pointer as ensureActive() will take care of ensuring the correct engine is active anway. --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 46 ++++++++-------------- src/opengl/qgl.cpp | 15 +++++++ src/opengl/qgl_p.h | 1 + src/opengl/qglframebufferobject.cpp | 12 ++++-- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index f174306..a7c7426 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -175,8 +175,6 @@ public: void updateDepthClip(); void systemStateChanged(); uint use_system_clip : 1; - - QPaintEngine *last_engine; }; @@ -830,10 +828,11 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) { Q_D(QGL2PaintEngineEx); - ensureActive(); if (pen.style() == Qt::NoPen) return; + ensureActive(); + if ( (pen.isCosmetic() && (pen.style() == Qt::SolidLine)) && (pen.widthF() < 2.5f) ) { // We only handle solid, cosmetic pens with a width of 1 pixel @@ -1051,10 +1050,19 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) Q_D(QGL2PaintEngineEx); // qDebug("QGL2PaintEngineEx::begin()"); - d->drawable.setDevice(pdev); - d->drawable.makeCurrent(); d->ctx = d->drawable.context(); + + if (d->ctx->d_ptr->active_engine) { + QGL2PaintEngineEx *engine = static_cast(d->ctx->d_ptr->active_engine); + QGL2PaintEngineExPrivate *p = static_cast(engine->d_ptr); + p->transferMode(BrushDrawingMode); + p->drawable.doneCurrent(); + } + + d->ctx->d_ptr->active_engine = this; + + d->drawable.makeCurrent(); QSize sz = d->drawable.size(); d->width = sz.width(); d->height = sz.height(); @@ -1064,14 +1072,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) qt_resolve_version_2_0_functions(d->ctx); #endif - d->last_engine = d->ctx->d_ptr->active_engine; - d->ctx->d_ptr->active_engine = this; - - if (d->last_engine) { - QGL2PaintEngineEx *engine = static_cast(d->last_engine); - static_cast(engine->d_ptr)->transferMode(BrushDrawingMode); - } - if (!d->shaderManager) d->shaderManager = new QGLEngineShaderManager(d->ctx); @@ -1115,8 +1115,8 @@ bool QGL2PaintEngineEx::end() Q_D(QGL2PaintEngineEx); QGLContext *ctx = d->ctx; if (ctx->d_ptr->active_engine != this) { - QGL2PaintEngineEx *engine = static_cast(d->last_engine); - if (engine) { + QGL2PaintEngineEx *engine = static_cast(ctx->d_ptr->active_engine); + if (engine && engine->isActive()) { QGL2PaintEngineExPrivate *p = static_cast(engine->d_ptr); p->transferMode(BrushDrawingMode); p->drawable.doneCurrent(); @@ -1128,19 +1128,7 @@ bool QGL2PaintEngineEx::end() d->transferMode(BrushDrawingMode); d->drawable.swapBuffers(); d->drawable.doneCurrent(); - d->ctx->d_ptr->active_engine = d->last_engine; - - if (d->last_engine) { - QGL2PaintEngineEx *engine = static_cast(d->last_engine); - QGL2PaintEngineExPrivate *p = static_cast(engine->d_ptr); - - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - - glViewport(0, 0, p->width, p->height); - engine->setState(engine->state()); - p->updateDepthClip(); - } + d->ctx->d_ptr->active_engine = 0; return false; } @@ -1152,7 +1140,7 @@ void QGL2PaintEngineEx::ensureActive() if (isActive() && ctx->d_ptr->active_engine != this) { QGL2PaintEngineEx *engine = static_cast(ctx->d_ptr->active_engine); - if (engine) { + if (engine && engine->isActive()) { QGL2PaintEngineExPrivate *p = static_cast(engine->d_ptr); p->transferMode(BrushDrawingMode); p->drawable.doneCurrent(); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 0a2a196..62a592a 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4391,6 +4391,15 @@ void QGLDrawable::swapBuffers() void QGLDrawable::makeCurrent() { + previous_fbo = 0; + if (!pixmapData && !fbo) { + QGLContext *ctx = context(); + previous_fbo = ctx->d_ptr->current_fbo; + ctx->d_ptr->current_fbo = 0; + if (previous_fbo) + glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); + } + if (widget) widget->makeCurrent(); #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) @@ -4428,6 +4437,12 @@ void QGLDrawable::doneCurrent() } #endif + if (previous_fbo) { + QGLContext *ctx = context(); + ctx->d_ptr->current_fbo = previous_fbo; + glBindFramebuffer(GL_FRAMEBUFFER_EXT, previous_fbo); + } + if (fbo && !wasBound) fbo->release(); } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index b421eee..9657416 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -333,6 +333,7 @@ private: #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) QGLPixmapData *pixmapData; #endif + int previous_fbo; }; // GL extension definitions diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 338ce1f..3e7ca0a 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -804,8 +804,10 @@ bool QGLFramebufferObject::bind() const QGLContext *context = QGLContext::currentContext(); if (d->valid && context) { // Save the previous setting to automatically restore in release(). - d->previous_fbo = context->d_ptr->current_fbo; - context->d_ptr->current_fbo = d->fbo; + if (context->d_ptr->current_fbo != d->fbo) { + d->previous_fbo = context->d_ptr->current_fbo; + context->d_ptr->current_fbo = d->fbo; + } } return d->valid; } @@ -834,8 +836,10 @@ bool QGLFramebufferObject::release() const QGLContext *context = QGLContext::currentContext(); if (context) { // Restore the previous setting for stacked framebuffer objects. - context->d_ptr->current_fbo = d->previous_fbo; - glBindFramebuffer(GL_FRAMEBUFFER_EXT, d->previous_fbo); + if (d->previous_fbo != context->d_ptr->current_fbo) { + context->d_ptr->current_fbo = d->previous_fbo; + glBindFramebuffer(GL_FRAMEBUFFER_EXT, d->previous_fbo); + } d->previous_fbo = 0; } -- cgit v0.12 From 855022d6108f6b3c90832e742217c50550af717d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 26 May 2009 10:58:30 +0200 Subject: Avoided expensive image upload for GL pixmap backend for QPixmap::fill. In the fill case we can simply set a flag saying the pixmap needs to be filled, and then when painting on the pixmap we start by filling the background using glClear via the existing QGLDrawable::autoFillBackground interface. --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 8 +++- src/opengl/qgl.cpp | 4 ++ src/opengl/qpixmapdata_gl.cpp | 46 +++++++++++++++++----- src/opengl/qpixmapdata_gl_p.h | 12 +++++- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index a7c7426..aafa6de 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1095,7 +1095,13 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) glDisable(GL_SCISSOR_TEST); QGLPixmapData *source = d->drawable.copyOnBegin(); - if (source) { + if (d->drawable.autoFillBackground()) { + QColor color = d->drawable.backgroundColor(); + + float alpha = color.alphaF(); + glClearColor(color.redF() * alpha, color.greenF() * alpha, color.blueF() * alpha, alpha); + glClear(GL_COLOR_BUFFER_BIT); + } else if (source) { d->transferMode(ImageDrawingMode); source->bind(false); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 62a592a..0be70d7 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4525,6 +4525,8 @@ QColor QGLDrawable::backgroundColor() const { if (widget) return widget->palette().brush(widget->backgroundRole()).color(); + else if (pixmapData) + return pixmapData->fillColor(); return QApplication::palette().brush(QPalette::Background).color(); } @@ -4547,6 +4549,8 @@ bool QGLDrawable::autoFillBackground() const { if (widget) return widget->autoFillBackground(); + else if (pixmapData) + return pixmapData->needsFill(); else return false; } diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index c89b99b..85bcda5 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -103,6 +103,7 @@ QGLPixmapData::QGLPixmapData(PixelType type) , m_engine(0) , m_ctx(0) , m_dirty(false) + , m_hasFillColor(false) { setSerialNumber(++qt_gl_pixmap_serial); } @@ -196,6 +197,13 @@ void QGLPixmapData::fromImage(const QImage &image, resize(image.width(), image.height()); m_source = image; m_dirty = true; + m_hasFillColor = false; + + if (m_textureId) { + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + glDeleteTextures(1, &m_textureId); + m_textureId = 0; + } } bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect) @@ -222,7 +230,11 @@ void QGLPixmapData::fill(const QColor &color) if (!isValid()) return; - if (!m_source.isNull()) { + if (useFramebufferObjects()) { + m_source = QImage(); + m_hasFillColor = true; + m_fillColor = color; + } else if (!m_source.isNull()) { m_source.fill(PREMUL(color.rgba())); } else { // ## TODO: improve performance here @@ -243,14 +255,18 @@ QImage QGLPixmapData::toImage() const if (!isValid()) return QImage(); - if (m_renderFbo) + if (m_renderFbo) { copyBackFromRenderFbo(true); - else if (!m_source.isNull()) + } else if (!m_source.isNull()) { return m_source; - else if (m_dirty) - return QImage(m_width, m_height, QImage::Format_ARGB32_Premultiplied); - else + } else if (m_dirty || m_hasFillColor) { + QImage img(m_width, m_height, QImage::Format_ARGB32_Premultiplied); + if (m_hasFillColor) + img.fill(PREMUL(m_fillColor.rgba())); + return img; + } else { ensureCreated(); + } QGLShareContextScope ctx(qt_gl_share_widget()->context()); extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); @@ -272,6 +288,8 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const if (!isValid()) return; + m_hasFillColor = false; + const QGLContext *share_ctx = qt_gl_share_widget()->context(); QGLShareContextScope ctx(share_ctx); @@ -356,9 +374,12 @@ QPaintEngine* QGLPixmapData::paintEngine() const return m_engine; else if (!useFramebufferObjects()) { m_dirty = true; - if (m_source.size() != size()) m_source = QImage(size(), QImage::Format_ARGB32_Premultiplied); + if (m_hasFillColor) { + m_source.fill(PREMUL(m_fillColor.rgba())); + m_hasFillColor = false; + } return m_source.paintEngine(); } @@ -394,10 +415,17 @@ QPaintEngine* QGLPixmapData::paintEngine() const GLuint QGLPixmapData::bind(bool copyBack) const { - if (m_renderFbo && copyBack) + if (m_renderFbo && copyBack) { copyBackFromRenderFbo(true); - else + } else { + if (m_hasFillColor) { + m_dirty = true; + m_source = QImage(m_width, m_height, QImage::Format_ARGB32_Premultiplied); + m_source.fill(PREMUL(m_fillColor.rgba())); + m_hasFillColor = false; + } ensureCreated(); + } GLuint id = m_textureId; glBindTexture(GL_TEXTURE_2D, id); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 7e06db9..1b6b7ae 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -91,6 +91,9 @@ public: bool isUninitialized() const { return m_dirty && m_source.isNull(); } + bool needsFill() const { return m_hasFillColor; } + QColor fillColor() const { return m_fillColor; } + QSize size() const { return QSize(m_width, m_height); } int width() const { return m_width; } int height() const { return m_height; } @@ -119,8 +122,15 @@ private: mutable GLuint m_textureId; mutable QPaintEngine *m_engine; mutable QGLContext *m_ctx; - mutable bool m_dirty; mutable QImage m_source; + + // the texture is not in sync with the source image + mutable bool m_dirty; + + // fill has been called and no painting has been done, so the pixmap is + // represented by a single fill color + mutable QColor m_fillColor; + mutable bool m_hasFillColor; }; QT_END_NAMESPACE -- cgit v0.12 From 73e7d0cbed0261715f534d95f81055bf97ce4314 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 27 May 2009 11:45:52 +0200 Subject: Make WA_TranslucentBackground work on QGLWidget for X11 This patch enables QGLWidget's to have an ARGB visual on X11, alowing GL rendering on semi-transparent windows. Reviewed-By: Trond --- src/gui/kernel/qwidget_x11.cpp | 31 ++++-- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 10 ++ src/opengl/qgl.cpp | 2 +- src/opengl/qgl_x11.cpp | 116 ++++++++++++++++++++- src/opengl/qpaintengine_opengl.cpp | 2 +- 5 files changed, 146 insertions(+), 15 deletions(-) diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index b35740a..7e41ea1 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -893,15 +893,28 @@ void QWidgetPrivate::x11UpdateIsOpaque() int screen = xinfo.screen(); if (topLevel && X11->use_xrender && X11->argbVisuals[screen] && xinfo.depth() != 32) { - // recreate widget - QPoint pos = q->pos(); - bool visible = q->isVisible(); - if (visible) - q->hide(); - q->setParent(q->parentWidget(), q->windowFlags()); - q->move(pos); - if (visible) - q->show(); + + if (q->inherits("QGLWidget")) { + // We send QGLWidgets a ParentChange event which causes them to + // recreate their GL context, which in turn causes them to choose + // their visual again. Now that WA_TranslucentBackground is set, + // QGLContext::chooseVisual will select an ARGB visual. + QEvent e(QEvent::ParentChange); + QApplication::sendEvent(q, &e); + } + else { + // For regular widgets, reparent them with their parent which + // also triggers a recreation of the native window + QPoint pos = q->pos(); + bool visible = q->isVisible(); + if (visible) + q->hide(); + + q->setParent(q->parentWidget(), q->windowFlags()); + q->move(pos); + if (visible) + q->show(); + } } #endif } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index aafa6de..5c8b364 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1083,6 +1083,16 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) // qDebug("You should see green now"); // sleep(5); + const QColor &c = d->drawable.backgroundColor(); + glClearColor(c.redF(), c.greenF(), c.blueF(), d->drawable.format().alpha() ? c.alphaF() : 1.0); + if (d->drawable.context()->d_func()->clear_on_painter_begin && d->drawable.autoFillBackground()) { + GLbitfield clearBits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; +#ifndef QT_OPENGL_ES + clearBits |= GL_ACCUM_BUFFER_BIT; +#endif + glClear(clearBits); + } + d->brushTextureDirty = true; d->brushUniformsDirty = true; d->matrixDirty = true; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 0be70d7..9626a3d 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3306,7 +3306,7 @@ bool QGLWidget::event(QEvent *e) glFinish(); doneCurrent(); } else if (e->type() == QEvent::ParentChange) { - if (d->glcx->d_func()->screen != d->xinfo.screen()) { + if (d->glcx->d_func()->screen != d->xinfo.screen() || testAttribute(Qt::WA_TranslucentBackground)) { setContext(new QGLContext(d->glcx->requestedFormat(), this)); // ### recreating the overlay isn't supported atm } diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 28c34de..aba1e5c 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -533,11 +533,22 @@ void *QGLContext::chooseVisual() void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) { Q_D(QGLContext); - int spec[40]; + int spec[45]; int i = 0; spec[i++] = GLX_LEVEL; spec[i++] = f.plane(); const QX11Info *xinfo = qt_x11Info(d->paintDevice); + bool useFBConfig = false; + +#if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) + QWidget* widget = 0; + if (d->paintDevice->devType() == QInternal::Widget) + widget = static_cast(d->paintDevice); + + // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual + if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender) + useFBConfig = true; +#endif #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) static bool useTranspExt = false; @@ -565,28 +576,41 @@ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) useTranspExtChecked = true; } - if (f.plane() && useTranspExt) { + if (f.plane() && useTranspExt && !useFBConfig) { // Required to avoid non-transparent overlay visual(!) on some systems spec[i++] = GLX_TRANSPARENT_TYPE_EXT; spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; } #endif +#if defined(GLX_VERSION_1_3) + // GLX_RENDER_TYPE is only in glx >=1.3 + if (useFBConfig) { + spec[i++] = GLX_RENDER_TYPE; + spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + } +#endif + if (f.doubleBuffer()) spec[i++] = GLX_DOUBLEBUFFER; + if (useFBConfig) + spec[i++] = True; if (f.depth()) { spec[i++] = GLX_DEPTH_SIZE; spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); } if (f.stereo()) { spec[i++] = GLX_STEREO; + if (useFBConfig) + spec[i++] = True; } if (f.stencil()) { spec[i++] = GLX_STENCIL_SIZE; spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); } if (f.rgba()) { - spec[i++] = GLX_RGBA; + if (!useFBConfig) + spec[i++] = GLX_RGBA; spec[i++] = GLX_RED_SIZE; spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); spec[i++] = GLX_GREEN_SIZE; @@ -621,8 +645,86 @@ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) spec[i++] = f.samples() == -1 ? 4 : f.samples(); } +#if defined(GLX_VERSION_1_3) + if (useFBConfig) { + spec[i++] = GLX_DRAWABLE_TYPE; + switch(d->paintDevice->devType()) { + case QInternal::Pixmap: + spec[i++] = GLX_PIXMAP_BIT; + break; + case QInternal::Pbuffer: + spec[i++] = GLX_PBUFFER_BIT; + break; + default: + qWarning("QGLContext: Unknown paint device type %d", d->paintDevice->devType()); + // Fall-through & assume it's a window + case QInternal::Widget: + spec[i++] = GLX_WINDOW_BIT; + break; + }; + } +#endif + spec[i] = XNone; - return glXChooseVisual(xinfo->display(), xinfo->screen(), spec); + + + XVisualInfo* chosenVisualInfo = 0; + +#if defined(GLX_VERSION_1_3) + while (useFBConfig) { + GLXFBConfig *configs; + int configCount = 0; + configs = glXChooseFBConfig(xinfo->display(), xinfo->screen(), spec, &configCount); + + if (!configs) + break; // fallback to trying glXChooseVisual + + for (i = 0; i < configCount; ++i) { + XVisualInfo* vi; + vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]); + if (!vi) + continue; + +#if !defined(QT_NO_XRENDER) + QWidget* w = 0; + if (d->paintDevice->devType() == QInternal::Widget) + w = static_cast(d->paintDevice); + + if (w && w->testAttribute(Qt::WA_TranslucentBackground) && f.alpha()) { + // Attempt to find a config who's visual has a proper alpha channel + XRenderPictFormat *pictFormat; + pictFormat = XRenderFindVisualFormat(xinfo->display(), vi->visual); + + if (pictFormat && (pictFormat->type == PictTypeDirect) && pictFormat->direct.alphaMask) { + // The pict format for the visual matching the FBConfig indicates ARGB + if (chosenVisualInfo) + XFree(chosenVisualInfo); + chosenVisualInfo = vi; + break; + } + } else +#endif //QT_NO_XRENDER + if (chosenVisualInfo) { + // If we've got a visual we can use and we're not trying to find one with a + // real alpha channel, we might as well just use the one we've got + break; + } + + if (!chosenVisualInfo) + chosenVisualInfo = vi; // Have something to fall back to + else + XFree(vi); + } + + XFree(configs); + break; + } +#endif // defined(GLX_VERSION_1_3) + + if (!chosenVisualInfo) + chosenVisualInfo = glXChooseVisual(xinfo->display(), xinfo->screen(), spec); + + return chosenVisualInfo; } @@ -1191,6 +1293,12 @@ void QGLWidget::setContext(QGLContext *context, d_func()->xinfo = parentWidget()->d_func()->xinfo; } + // If the application has set WA_TranslucentBackground and not explicitly set + // the alpha buffer size to zero, modify the format so it have an alpha channel + QGLFormat& fmt = d->glcx->d_func()->glFormat; + if (testAttribute(Qt::WA_TranslucentBackground) && fmt.alphaBufferSize() == -1) + fmt.setAlphaBufferSize(1); + bool createFailed = false; if (!d->glcx->isValid()) { if (!d->glcx->create(shareContext ? shareContext : oldcx)) diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index d98cd7c..d5bf1dc 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -1331,7 +1331,7 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev) d->offscreen.begin(); const QColor &c = d->drawable.backgroundColor(); - glClearColor(c.redF(), c.greenF(), c.blueF(), 1.0); + glClearColor(c.redF(), c.greenF(), c.blueF(), d->drawable.format().alpha() ? c.alphaF() : 1.0); if (d->drawable.context()->d_func()->clear_on_painter_begin && d->drawable.autoFillBackground()) { GLbitfield clearBits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; #ifndef QT_OPENGL_ES -- cgit v0.12 From 71cb35e942b94e4dba2055acdebbf90c352da762 Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Wed, 27 May 2009 13:23:53 +0200 Subject: Add comparation of images with indexed color Previously, two images with indexed colors were not equal if their color tables were not the same. The image are not compared by the value of the pixels Reviewed-by: Samuel --- src/gui/image/qimage.cpp | 10 +++++----- tests/auto/qimage/tst_qimage.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 25c68bc..c1c5631 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4853,8 +4853,6 @@ bool QImage::operator==(const QImage & i) const return false; if (d->format != Format_RGB32) { - if (d->colortable != i.d->colortable) - return false; if (d->format >= Format_ARGB32) { // all bits defined const int n = d->width * d->depth / 8; if (n == d->bytes_per_line && n == i.d->bytes_per_line) { @@ -4867,11 +4865,13 @@ bool QImage::operator==(const QImage & i) const } } } else { - int w = width(); - int h = height(); + const int w = width(); + const int h = height(); + const QVector &colortable = d->colortable; + const QVector &icolortable = i.d->colortable; for (int y=0; y colorTable(256); + for (int i = 0; i < 256; ++i) + colorTable[i] = qRgb(i, i, i); + img.setColorTable(colorTable); + + for (int i = 0; i < 256; ++i) { + img.setPixel(i, 0, i); + } + + QImage imgInverted(256, 1, QImage::Format_Indexed8); + QVector invertedColorTable(256); + for (int i = 0; i < 256; ++i) + invertedColorTable[255-i] = qRgb(i, i, i); + imgInverted.setColorTable(invertedColorTable); + + for (int i = 0; i < 256; ++i) { + imgInverted.setPixel(i, 0, (255-i)); + } + + QCOMPARE(img, imgInverted); +} + QTEST_MAIN(tst_QImage) #include "tst_qimage.moc" -- cgit v0.12 From 962d216ce9f9f1e6bd73fe43e3d2a7c86f64b75f Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 27 May 2009 14:02:14 +0200 Subject: Make QGLWidgets have the same background colour as QWidgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QWidgets are filled with Qt::transparent when WA_TranslucentBackground is set, reguardless of what their background colour has been set to. This patch makes QGLWidgets behave the same way. Reviewed-By: Samuel Rødal --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 23 ++++++++-------------- src/opengl/qgl.cpp | 5 +++++ src/opengl/qgl_p.h | 1 + src/opengl/qpaintengine_opengl.cpp | 10 ++++++++-- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 5c8b364..f7dbed3 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1083,16 +1083,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) // qDebug("You should see green now"); // sleep(5); - const QColor &c = d->drawable.backgroundColor(); - glClearColor(c.redF(), c.greenF(), c.blueF(), d->drawable.format().alpha() ? c.alphaF() : 1.0); - if (d->drawable.context()->d_func()->clear_on_painter_begin && d->drawable.autoFillBackground()) { - GLbitfield clearBits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; -#ifndef QT_OPENGL_ES - clearBits |= GL_ACCUM_BUFFER_BIT; -#endif - glClear(clearBits); - } - d->brushTextureDirty = true; d->brushUniformsDirty = true; d->matrixDirty = true; @@ -1105,11 +1095,14 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) glDisable(GL_SCISSOR_TEST); QGLPixmapData *source = d->drawable.copyOnBegin(); - if (d->drawable.autoFillBackground()) { - QColor color = d->drawable.backgroundColor(); - - float alpha = color.alphaF(); - glClearColor(color.redF() * alpha, color.greenF() * alpha, color.blueF() * alpha, alpha); + if (d->drawable.context()->d_func()->clear_on_painter_begin && d->drawable.autoFillBackground()) { + if (d->drawable.hasTransparentBackground()) + glClearColor(0.0, 0.0, 0.0, 0.0); + else { + const QColor &c = d->drawable.backgroundColor(); + float alpha = c.alphaF(); + glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); + } glClear(GL_COLOR_BUFFER_BIT); } else if (source) { d->transferMode(ImageDrawingMode); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 9626a3d..ced3452 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4530,6 +4530,11 @@ QColor QGLDrawable::backgroundColor() const return QApplication::palette().brush(QPalette::Background).color(); } +bool QGLDrawable::hasTransparentBackground() const +{ + return widget && widget->testAttribute(Qt::WA_TranslucentBackground); +} + QGLContext *QGLDrawable::context() const { if (widget) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 9657416..b1a63b5 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -314,6 +314,7 @@ public: QColor backgroundColor() const; QGLContext *context() const; bool autoFillBackground() const; + bool hasTransparentBackground() const; #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) QGLPixmapData *copyOnBegin() const; diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index d5bf1dc..e3d8a1d 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -1330,9 +1330,15 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev) d->offscreen.begin(); - const QColor &c = d->drawable.backgroundColor(); - glClearColor(c.redF(), c.greenF(), c.blueF(), d->drawable.format().alpha() ? c.alphaF() : 1.0); if (d->drawable.context()->d_func()->clear_on_painter_begin && d->drawable.autoFillBackground()) { + + if (d->drawable.hasTransparentBackground()) + glClearColor(0.0, 0.0, 0.0, 0.0); + else { + const QColor &c = d->drawable.backgroundColor(); + glClearColor(c.redF(), c.greenF(), c.blueF(), 1.0); + } + GLbitfield clearBits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; #ifndef QT_OPENGL_ES clearBits |= GL_ACCUM_BUFFER_BIT; -- cgit v0.12 From 16275ff6b9abc085a498428170047f2bee9ee30b Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 27 May 2009 14:28:06 +0200 Subject: A few html code generator fixes. There was an empty
    element with a name that came after it. I moved the name inside the
    element. And there were some elements that began inside one element and ended inside the next element. I just removed them, because they didn't really add anything. And I made the "Access functions:" bold. --- tools/qdoc3/htmlgenerator.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 798cbb5..e2e6950 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -2207,18 +2207,14 @@ void HtmlGenerator::generateSectionList(const Section& section, else { if (twoColumn && i == (int) (section.members.count() + 1) / 2) out() << "
      \n"; - out() << "
    • "; + out() << "
    • "; } - if (style == CodeMarker::Accessors) - out() << ""; generateSynopsis(*m, relative, marker, style, name_alignment); - if (style == CodeMarker::Accessors) - out() << ""; if (name_alignment) out() << "\n"; else - out() << "
    • \n"; + out() << "
    \n"; i++; ++m; } @@ -2283,8 +2279,10 @@ void HtmlGenerator::generateSynopsis(const Node *node, marked.replace("<@param>", ""); marked.replace("", ""); - if (style == CodeMarker::Summary) - marked.replace("@name>", "b>"); + if (style == CodeMarker::Summary) { + marked.replace("<@name>", ""); // was "" + marked.replace("", ""); // was "" + } if (style == CodeMarker::SeparateList) { QRegExp extraRegExp("<@extra>.*"); @@ -3090,7 +3088,7 @@ void HtmlGenerator::generateDetailedMember(const Node *node, section.members += property->resetters(); if (!section.members.isEmpty()) { - out() << "

    Access functions:

    \n"; + out() << "

    Access functions:

    \n"; generateSectionList(section, node, marker, CodeMarker::Accessors); } } -- cgit v0.12 From 3a61a448b92b4f7c7ee02196340d3bcb75d067fb Mon Sep 17 00:00:00 2001 From: diaulas Date: Tue, 12 May 2009 14:15:34 +0200 Subject: Dont show children when parent is not visible in QGraphicsItem When setVisible() is called on a QGraphicsItem, if the parent of that item was hidden, the child shouldn't be actually shown. Task-number: 197802 Reviewed-by: leo Reviewed-by: alexis --- src/gui/graphicsview/qgraphicsitem.cpp | 5 ++++ tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 32 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 4908296..b6a7386 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1522,6 +1522,11 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo if (visible == quint32(newVisible)) return; + QGraphicsItem *parent(q_ptr->parentItem()); + if (parent && newVisible && !parent->d_ptr->visible) { + return; + } + // Modify the property. const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange, quint32(newVisible))); diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 58a17ea..d477135 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -123,6 +123,7 @@ private slots: void destruction(); void scene(); void parentItem(); + void childrenVisibility(); void setParentItem(); void children(); void flags(); @@ -549,6 +550,37 @@ void tst_QGraphicsItem::parentItem() delete item2; } +void tst_QGraphicsItem::childrenVisibility() +{ + QGraphicsScene scene; + QGraphicsRectItem item(QRectF(0,0,20,20)); + + QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(0,0,10,10), &item); + scene.addItem(&item); + + //freshly created: both visible + QVERIFY(item.isVisible()); + QVERIFY(item2->isVisible()); + //hide child: parent visible, child not + item2->hide(); + QVERIFY(item.isVisible()); + QVERIFY(!item2->isVisible()); + //hide parent: parent and child invisible + item.hide(); + QVERIFY(!item.isVisible()); + QVERIFY(!item2->isVisible()); + //ask to show the child: parent and child invisible anyways + item2->show(); + QVERIFY(!item.isVisible()); + QVERIFY(!item2->isVisible()); + //show the parent: both parent and child visible + item.show(); + QVERIFY(item.isVisible()); + QVERIFY(item2->isVisible()); + + delete item2; +} + void tst_QGraphicsItem::setParentItem() { QGraphicsScene scene; -- cgit v0.12 From 5675d15eebd76fde43bc9305347c3b7833a7d893 Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Wed, 27 May 2009 15:03:00 +0200 Subject: Fixes for merge-request #407 Removed unused line and added task number to autotest. --- src/gui/graphicsview/qgraphicsitem.cpp | 5 +- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 70 ++++++++++++++------------ 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b6a7386..e8ace65 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1522,10 +1522,9 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo if (visible == quint32(newVisible)) return; - QGraphicsItem *parent(q_ptr->parentItem()); - if (parent && newVisible && !parent->d_ptr->visible) { + // Don't show child if parent is not visible + if (parent && newVisible && !parent->d_ptr->visible) return; - } // Modify the property. const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange, diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index d477135..34a6ab1 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -123,7 +123,6 @@ private slots: void destruction(); void scene(); void parentItem(); - void childrenVisibility(); void setParentItem(); void children(); void flags(); @@ -227,6 +226,7 @@ private slots: void task240400_clickOnTextItem_data(); void task240400_clickOnTextItem(); void task243707_addChildBeforeParent(); + void task197802_childrenVisibility(); }; void tst_QGraphicsItem::init() @@ -550,37 +550,6 @@ void tst_QGraphicsItem::parentItem() delete item2; } -void tst_QGraphicsItem::childrenVisibility() -{ - QGraphicsScene scene; - QGraphicsRectItem item(QRectF(0,0,20,20)); - - QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(0,0,10,10), &item); - scene.addItem(&item); - - //freshly created: both visible - QVERIFY(item.isVisible()); - QVERIFY(item2->isVisible()); - //hide child: parent visible, child not - item2->hide(); - QVERIFY(item.isVisible()); - QVERIFY(!item2->isVisible()); - //hide parent: parent and child invisible - item.hide(); - QVERIFY(!item.isVisible()); - QVERIFY(!item2->isVisible()); - //ask to show the child: parent and child invisible anyways - item2->show(); - QVERIFY(!item.isVisible()); - QVERIFY(!item2->isVisible()); - //show the parent: both parent and child visible - item.show(); - QVERIFY(item.isVisible()); - QVERIFY(item2->isVisible()); - - delete item2; -} - void tst_QGraphicsItem::setParentItem() { QGraphicsScene scene; @@ -5378,7 +5347,7 @@ void tst_QGraphicsItem::task243707_addChildBeforeParent() // inconsistent internal state that can cause a crash. This test shows // one such crash. QGraphicsScene scene; - QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsWidget *widget = new QGraphicsWidget; QGraphicsWidget *widget2 = new QGraphicsWidget(widget); scene.addItem(widget2); QVERIFY(!widget2->parentItem()); @@ -5387,6 +5356,41 @@ void tst_QGraphicsItem::task243707_addChildBeforeParent() QVERIFY(!widget2->commonAncestorItem(widget)); } +void tst_QGraphicsItem::task197802_childrenVisibility() +{ + QGraphicsScene scene; + QGraphicsRectItem item(QRectF(0,0,20,20)); + + QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(0,0,10,10), &item); + scene.addItem(&item); + + //freshly created: both visible + QVERIFY(item.isVisible()); + QVERIFY(item2->isVisible()); + + //hide child: parent visible, child not + item2->hide(); + QVERIFY(item.isVisible()); + QVERIFY(!item2->isVisible()); + + //hide parent: parent and child invisible + item.hide(); + QVERIFY(!item.isVisible()); + QVERIFY(!item2->isVisible()); + + //ask to show the child: parent and child invisible anyways + item2->show(); + QVERIFY(!item.isVisible()); + QVERIFY(!item2->isVisible()); + + //show the parent: both parent and child visible + item.show(); + QVERIFY(item.isVisible()); + QVERIFY(item2->isVisible()); + + delete item2; +} + void tst_QGraphicsItem::boundingRegion_data() { QTest::addColumn("line"); -- cgit v0.12 From d8a2e52e4db873a2cfd39630df47b61bec502fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= Date: Fri, 15 May 2009 05:29:29 +0000 Subject: Memory of fixedKernel is never returned, found by cppcheck. --- src/gui/image/qpixmapfilter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 8631c8c..4e6adc0 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -401,6 +401,7 @@ static void convolute( } yk++; } + delete[] fixedKernel; } /*! -- cgit v0.12 From b66f7a2e95c32c64701a992f28d99e32f48e2db1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 27 May 2009 16:25:25 +0200 Subject: Optimized fast scaling of ARGB8565 images onto RGB16 images. There was an optimized blend function for this case but not an optimized scale function. Performance increase seems to be in the order of 5x. Reviewed-by: Trond --- src/gui/painting/qblendfunctions.cpp | 59 +++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 8f4a2bf..f83ff7b 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -104,6 +104,37 @@ struct Blend_RGB16_on_RGB16_ConstAlpha { quint32 m_ialpha; }; +struct Blend_ARGB24_on_RGB16_SourceAlpha { + inline void write(quint16 *dst, qargb8565 src) { + const uint alpha = src.alpha(); + if (alpha) { + quint16 s = qrgb565(src).rawValue(); + if (alpha < 255) + s += BYTE_MUL_RGB16(*dst, 255 - alpha); + *dst = s; + } + } +}; + +struct Blend_ARGB24_on_RGB16_SourceAndConstAlpha { + inline Blend_ARGB24_on_RGB16_SourceAndConstAlpha(quint32 alpha) { + m_alpha = (alpha * 255) >> 8; + } + + inline void write(quint16 *dst, qargb8565 src) { + src = src.byte_mul(src.alpha(m_alpha)); + const uint alpha = src.alpha(); + if (alpha) { + quint16 s = qrgb565(src).rawValue(); + if (alpha < 255) + s += BYTE_MUL_RGB16(*dst, 255 - alpha); + *dst = s; + } + } + + quint32 m_alpha; +}; + struct Blend_ARGB32_on_RGB16_SourceAlpha { inline void write(quint16 *dst, quint32 src) { const quint8 alpha = qAlpha(src); @@ -237,6 +268,32 @@ void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, } } +void qt_scale_image_argb24_on_rgb16(uchar *destPixels, int dbpl, + const uchar *srcPixels, int sbpl, + const QRectF &targetRect, + const QRectF &sourceRect, + const QRect &clip, + int const_alpha) +{ +#ifdef QT_DEBUG_DRAW + printf("qt_scale_argb24_on_rgb16: dst=(%p, %d), src=(%p, %d), target=(%d, %d), [%d x %d], src=(%d, %d) [%d x %d] alpha=%d\n", + destPixels, dbpl, srcPixels, sbpl, + targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), + sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height(), + const_alpha); +#endif + if (const_alpha == 256) { + Blend_ARGB24_on_RGB16_SourceAlpha noAlpha; + qt_scale_image_16bit(destPixels, dbpl, srcPixels, sbpl, + targetRect, sourceRect, clip, noAlpha); + } else { + Blend_ARGB24_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha); + qt_scale_image_16bit(destPixels, dbpl, srcPixels, sbpl, + targetRect, sourceRect, clip, constAlpha); + } +} + + void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, const QRectF &targetRect, @@ -874,7 +931,7 @@ SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = 0, // Format_ARGB32, qt_scale_image_argb32_on_rgb16, // Format_ARGB32_Premultiplied, qt_scale_image_rgb16_on_rgb16, // Format_RGB16, - 0, // Format_ARGB8565_Premultiplied, + qt_scale_image_argb24_on_rgb16, // Format_ARGB8565_Premultiplied, 0, // Format_RGB666, 0, // Format_ARGB6666_Premultiplied, 0, // Format_RGB555, -- cgit v0.12 From e24868e99ef0ffd8e5690761a798d731c4b71b26 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 27 May 2009 16:30:47 +0200 Subject: Fixed a possible assert in QGtkStyle We now set and unset the GTK_HAS_FOCUS flag on the same painting call only if focus is set instead of resetting it on each painting call. This is a tiny optimization but also kills a possible assert on certain versions of Gtk+ (as reported with Red Hat Enterprise Linux 5). Task-number: 254614 Reviewed-by: denis --- src/gui/styles/qgtkstyle.cpp | 63 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 14be518..0e54af8 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -940,10 +940,6 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, case PE_FrameLineEdit: { GtkWidget *gtkEntry = QGtk::gtkWidget(QLS("GtkEntry")); - if (option->state & State_HasFocus) - GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS); - else - GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS); gboolean interior_focus; gint focus_line_width; @@ -957,6 +953,9 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, if (!interior_focus && option->state & State_HasFocus) rect.adjust(focus_line_width, focus_line_width, -focus_line_width, -focus_line_width); + + if (option->state & State_HasFocus) + GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS); gtkPainter.paintShadow(gtkEntry, "entry", rect, option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, gtkEntry->style, @@ -965,6 +964,9 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, gtkPainter.paintShadow(gtkEntry, "entry", option->rect, option->state & State_Enabled ? GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, gtkEntry->style, QLS("GtkEntryShadowIn")); + + if (option->state & State_HasFocus) + GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS); } break; @@ -1050,17 +1052,13 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, GTK_WIDGET_SET_FLAGS(gtkButton, GTK_HAS_DEFAULT); gtkPainter.paintBox(gtkButton, "buttondefault", buttonRect, state, GTK_SHADOW_IN, style, isDefault ? QLS("d") : QString()); - } else - GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_DEFAULT); + } bool hasFocus = option->state & State_HasFocus; if (hasFocus) { key += QLS("def"); GTK_WIDGET_SET_FLAGS(gtkButton, GTK_HAS_FOCUS); - - } else { - GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_FOCUS); } if (!interiorFocus) @@ -1071,6 +1069,10 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, gtkPainter.paintBox(gtkButton, "button", buttonRect, state, shadow, style, key); + if (isDefault) + GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_DEFAULT); + if (hasFocus) + GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_FOCUS); } break; @@ -1334,6 +1336,8 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom GtkWidget *gtkToggleButton = QGtk::gtkWidget(buttonPath); QGtk::gtk_widget_set_direction(gtkToggleButton, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); if (gtkToggleButton && (appears_as_list || comboBox->editable)) { + if (focus) + GTK_WIDGET_SET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS); // Draw the combo box as a line edit with a button next to it if (comboBox->editable || appears_as_list) { GtkStateType frameState = (state == GTK_STATE_PRELIGHT) ? GTK_STATE_NORMAL : state; @@ -1347,22 +1351,16 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom else frameRect.setRight(arrowButtonRect.left()); - // Required for inner blue highlight with clearlooks - if (focus) { - GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS); - GTK_WIDGET_SET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS); - - } else { - GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS); - GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS); - } - // Fill the line edit background // We could have used flat_box with "entry_bg" but that is probably not worth the overhead uint resolve_mask = option->palette.resolve(); int xt = gtkEntry->style->xthickness; int yt = gtkEntry->style->ythickness; QRect contentRect = frameRect.adjusted(xt, yt, -xt, -yt); + // Required for inner blue highlight with clearlooks + if (focus) + GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS); + if (widget && widget->testAttribute(Qt::WA_SetPalette) && resolve_mask & (1 << QPalette::Base)) // Palette overridden by user p->fillRect(contentRect, option->palette.base().color()); @@ -1376,6 +1374,8 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom GTK_SHADOW_IN, gtkEntry->style, entryPath + QString::number(focus) + QString::number(comboBox->editable) + QString::number(option->direction)); + if (focus) + GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS); } GtkStateType buttonState = GTK_STATE_NORMAL; @@ -1394,22 +1394,21 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom gtkCachedPainter.paintBox( gtkToggleButton, "button", arrowButtonRect, buttonState, shadow, gtkToggleButton->style, buttonPath + QString::number(focus) + QString::number(option->direction)); - + if (focus) + GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS); } else { // Draw combo box as a button QRect buttonRect = option->rect; - if (focus) { // Clearlooks actually check the widget for the default state + if (focus) // Clearlooks actually check the widget for the default state GTK_WIDGET_SET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS); - - } else { - GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS); - } - gtkCachedPainter.paintBox(gtkToggleButton, "button", buttonRect, state, shadow, gtkToggleButton->style, buttonPath + QString::number(focus)); + if (focus) + GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS); + // Draw the separator between label and arrows QString vSeparatorPath = buttonPath + QLS(".GtkHBox.GtkVSeparator"); @@ -1775,15 +1774,12 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom shadow = GTK_SHADOW_IN; style = gtkPainter.getStyle(gtkSpinButton); - if (option->state & State_HasFocus) - GTK_WIDGET_SET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS); - else - GTK_WIDGET_UNSET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS); QString key; - - if (option->state & State_HasFocus) + if (option->state & State_HasFocus) { key = QLS("f"); + GTK_WIDGET_SET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS); + } uint resolve_mask = option->palette.resolve(); @@ -1816,6 +1812,9 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key); else gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key); + + if (option->state & State_HasFocus) + GTK_WIDGET_UNSET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS); } if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) { -- cgit v0.12 From 884eb97fe9eab4ee84dd8aafb026fd918906cf9a Mon Sep 17 00:00:00 2001 From: Matteo Bertozzi Date: Sun, 17 May 2009 15:19:31 +0200 Subject: Speed up util/normalize dir iteration Use QDirIterator to speed up iterating over directories in normalize util. Reviewed-by: Eskil --- util/normalize/main.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/util/normalize/main.cpp b/util/normalize/main.cpp index 905c1ec..b16335e 100644 --- a/util/normalize/main.cpp +++ b/util/normalize/main.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ #include -#include +#include #include #include #include @@ -140,18 +140,14 @@ void check(const QString &fileName) void traverse(const QString &path) { - QDir dir(path); - dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoSymLinks); - - const QFileInfoList list = dir.entryInfoList(); - for (int i = 0; i < list.count(); ++i) { - const QFileInfo fi = list.at(i); - if (fi.fileName() == QLatin1String(".") || fi.fileName() == QLatin1String("..")) - continue; - if (fi.fileName().endsWith(".cpp")) - check(path + fi.fileName()); - if (fi.isDir()) - traverse(path + fi.fileName() + "/"); // recurse + QDirIterator dirIterator(path, QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files | QDir::NoSymLinks); + + while (dirIterator.hasNext()) { + QString filePath = dirIterator.next(); + if (filePath.endsWith(".cpp")) + check(filePath); + else if (QFileInfo(filePath).isDir()) + traverse(filePath); // recurse } } -- cgit v0.12 From 2be3c937fdca26287f74dd58cc217cb51924cf8a Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 27 May 2009 17:21:53 +0200 Subject: QNetworkReply internals: do not assert when aborted and reading data ...but just silently return. This is ok because at another location in QNetworkReplyImplPrivate we do the same. Reviewed-by: Thiago Task-number: 254638 --- src/network/access/qnetworkreplyimpl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 79c3d1a..6f715e5 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -382,7 +382,8 @@ void QNetworkReplyImplPrivate::feed(const QByteArray &data) void QNetworkReplyImplPrivate::feed(QIODevice *data) { Q_Q(QNetworkReplyImpl); - Q_ASSERT(q->isOpen()); + if (!q->isOpen()) + return; // read until EOF from data if (copyDevice) { -- cgit v0.12 From d0bc0a26f8ac4c2f02819c262b8aa7c3dd1cad3b Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 27 May 2009 17:25:01 +0200 Subject: Fixed: Setting a border using stylesheet for QComboBox adds an unwated frame. This was already fix. But there was still a frame if there was a stylesheet on the applicaiton. The reason is that the frame's constructor call the style for some hints. And later the combobox will query the style again for the frame hint, before the view get polished. The problem is that the StyleSheetStyle will fill the css cache with wrong information on the first call. This is not visible if there is no stylesheet as in the constructor, the widget style is still the default application stylesheet if there is no global applicaiton stylesheet. Task-number: 254589 Reviewed-by: jbache BT: --- src/gui/styles/qstylesheetstyle.cpp | 9 ++++++--- tests/auto/qcombobox/tst_qcombobox.cpp | 8 +++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 714b8c5..bd80bb6 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -5252,9 +5252,12 @@ int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWi #ifndef QT_NO_COMBOBOX if (qobject_cast(w)) { QAbstractItemView *view = qFindChild(w); - QRenderRule subRule = renderRule(view, PseudoElement_None); - if (subRule.hasBox() || !subRule.hasNativeBorder()) - return QFrame::NoFrame; + if (view) { + view->ensurePolished(); + QRenderRule subRule = renderRule(view, PseudoElement_None); + if (subRule.hasBox() || !subRule.hasNativeBorder()) + return QFrame::NoFrame; + } } #endif // QT_NO_COMBOBOX break; diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index 2fff6d0..816b2e8 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -2171,7 +2171,7 @@ void tst_QComboBox::noScrollbar_data() QTest::newRow("everything and more") << QString::fromLatin1("QAbstractItemView { border: 1px 3px 5px 1px solid blue; " " padding: 2px 5px 3px 1px; margin: 2px 5px 3px 1px; } " " QAbstractItemView::item { border: 2px solid green; " - " padding: 1px 1px 2px 2px margin: 1px; } " ); + " padding: 1px 1px 2px 2px; margin: 1px; } " ); } void tst_QComboBox::noScrollbar() @@ -2179,10 +2179,11 @@ void tst_QComboBox::noScrollbar() QStringList initialContent; initialContent << "foo" << "bar" << "foobar" << "moo"; QFETCH(QString, stylesheet); + QString oldCss = qApp->styleSheet(); + qApp->setStyleSheet(stylesheet); { QComboBox comboBox; - comboBox.setStyleSheet(stylesheet); comboBox.addItems(initialContent); comboBox.show(); comboBox.resize(200, comboBox.height()); @@ -2196,7 +2197,6 @@ void tst_QComboBox::noScrollbar() { QTableWidget *table = new QTableWidget(2,2); QComboBox comboBox; - comboBox.setStyleSheet(stylesheet); comboBox.setView(table); comboBox.setModel(table->model()); comboBox.show(); @@ -2207,6 +2207,8 @@ void tst_QComboBox::noScrollbar() QVERIFY(!comboBox.view()->horizontalScrollBar()->isVisible()); QVERIFY(!comboBox.view()->verticalScrollBar()->isVisible()); } + + qApp->setStyleSheet(oldCss); } void tst_QComboBox::setItemDelegate() -- cgit v0.12 From 665614ede1de33d5ccfacb81c1463896a99ffd86 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 27 May 2009 18:21:30 +0200 Subject: Remove used variable olsFrameStyle was old. Reviewed-by: jbache --- src/gui/widgets/qframe.cpp | 4 +--- src/gui/widgets/qframe_p.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/gui/widgets/qframe.cpp b/src/gui/widgets/qframe.cpp index 6f81331..22a990b 100644 --- a/src/gui/widgets/qframe.cpp +++ b/src/gui/widgets/qframe.cpp @@ -59,8 +59,7 @@ QFramePrivate::QFramePrivate() midLineWidth(0), frameWidth(0), leftFrameWidth(0), rightFrameWidth(0), - topFrameWidth(0), bottomFrameWidth(0), - oldFrameStyle(QFrame::NoFrame | QFrame::Plain) + topFrameWidth(0), bottomFrameWidth(0) { } @@ -333,7 +332,6 @@ void QFrame::setFrameStyle(int style) d->frameStyle = (short)style; update(); d->updateFrameWidth(); - d->oldFrameStyle = (short)style; } /*! diff --git a/src/gui/widgets/qframe_p.h b/src/gui/widgets/qframe_p.h index 3ea0c8b..537f5bf 100644 --- a/src/gui/widgets/qframe_p.h +++ b/src/gui/widgets/qframe_p.h @@ -74,7 +74,6 @@ public: short frameWidth; short leftFrameWidth, rightFrameWidth; short topFrameWidth, bottomFrameWidth; - short oldFrameStyle; inline void init(); -- cgit v0.12 From a9308e78e9b8aea110316c18489dd222936e13e4 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 27 May 2009 18:50:20 +0200 Subject: Compile without OpenGL Reviewed-by: Alexis --- examples/animation/sub-attaq/mainwindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/animation/sub-attaq/mainwindow.cpp b/examples/animation/sub-attaq/mainwindow.cpp index a166241..9cf9eb5 100644 --- a/examples/animation/sub-attaq/mainwindow.cpp +++ b/examples/animation/sub-attaq/mainwindow.cpp @@ -43,11 +43,11 @@ #include "mainwindow.h" #include "graphicsscene.h" +//Qt +#include #ifndef QT_NO_OPENGL - #include +#include #endif -//Qt -#include MainWindow::MainWindow() : QMainWindow(0) { -- cgit v0.12 From 8facefaef36ae313661bbdbcf317c374e35754cb Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 27 May 2009 19:04:55 +0200 Subject: Fixes sub-attaq in shadow build. Reviewed-by: Alexis --- examples/animation/sub-attaq/graphicsscene.cpp | 2 +- examples/animation/sub-attaq/subattaq.qrc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/animation/sub-attaq/graphicsscene.cpp b/examples/animation/sub-attaq/graphicsscene.cpp index f2d41bc..e773dae 100644 --- a/examples/animation/sub-attaq/graphicsscene.cpp +++ b/examples/animation/sub-attaq/graphicsscene.cpp @@ -120,7 +120,7 @@ GraphicsScene::GraphicsScene(int x, int y, int width, int height, Mode mode) //parse the xml that contain all data of the game QXmlStreamReader reader; - QFile file(QDir::currentPath() + "/data.xml"); + QFile file(":data.xml"); file.open(QIODevice::ReadOnly); reader.setDevice(&file); LevelDescription currentLevel; diff --git a/examples/animation/sub-attaq/subattaq.qrc b/examples/animation/sub-attaq/subattaq.qrc index c76f8ef..80a3af1 100644 --- a/examples/animation/sub-attaq/subattaq.qrc +++ b/examples/animation/sub-attaq/subattaq.qrc @@ -34,5 +34,6 @@ pics/big/explosion/submarine/step2.png pics/big/explosion/submarine/step3.png pics/big/explosion/submarine/step4.png + data.xml -- cgit v0.12 From e4cd7640d98f229e777f0699d7b738a8b539c269 Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 27 May 2009 20:18:01 +0200 Subject: Restore undo compression for cut/del of selections This is a small fix to 4af30f47c37fd0e6826aca2984dd0f567dc7e465 --- src/gui/text/qtextcursor.cpp | 57 +++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index d12e3fe..b9e1c89 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -1361,12 +1361,15 @@ void QTextCursor::deleteChar() if (!d || !d->priv) return; - if (d->position == d->anchor) { - if (!d->canDelete(d->position)) - return; - d->adjusted_anchor = d->anchor = - d->priv->nextCursorPosition(d->anchor, QTextLayout::SkipCharacters); + if (d->position != d->anchor) { + removeSelectedText(); + return; } + + if (!d->canDelete(d->position)) + return; + d->adjusted_anchor = d->anchor = + d->priv->nextCursorPosition(d->anchor, QTextLayout::SkipCharacters); d->remove(); d->setX(); } @@ -1381,27 +1384,29 @@ void QTextCursor::deletePreviousChar() { if (!d || !d->priv) return; - - if (d->position == d->anchor) { - if (d->anchor < 1 || !d->canDelete(d->anchor-1)) - return; - d->anchor--; - - QTextDocumentPrivate::FragmentIterator fragIt = d->priv->find(d->anchor); - const QTextFragmentData * const frag = fragIt.value(); - int fpos = fragIt.position(); - QChar uc = d->priv->buffer().at(d->anchor - fpos + frag->stringPosition); - if (d->anchor > fpos && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { - // second half of a surrogate, check if we have the first half as well, - // if yes delete both at once - uc = d->priv->buffer().at(d->anchor - 1 - fpos + frag->stringPosition); - if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) - --d->anchor; - } - - d->adjusted_anchor = d->anchor; + + if (d->position != d->anchor) { + removeSelectedText(); + return; } - + + if (d->anchor < 1 || !d->canDelete(d->anchor-1)) + return; + d->anchor--; + + QTextDocumentPrivate::FragmentIterator fragIt = d->priv->find(d->anchor); + const QTextFragmentData * const frag = fragIt.value(); + int fpos = fragIt.position(); + QChar uc = d->priv->buffer().at(d->anchor - fpos + frag->stringPosition); + if (d->anchor > fpos && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { + // second half of a surrogate, check if we have the first half as well, + // if yes delete both at once + uc = d->priv->buffer().at(d->anchor - 1 - fpos + frag->stringPosition); + if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) + --d->anchor; + } + + d->adjusted_anchor = d->anchor; d->remove(); d->setX(); } @@ -1517,7 +1522,9 @@ void QTextCursor::removeSelectedText() if (!d || !d->priv || d->position == d->anchor) return; + d->priv->beginEditBlock(); d->remove(); + d->priv->endEditBlock(); d->setX(); } -- cgit v0.12