diff options
99 files changed, 3187 insertions, 2364 deletions
diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index 2e795e1439..06a6780a3d 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -14,7 +14,8 @@ defines += Q_QDOC \ QT_DEPRECATED_* \ Q_NO_USING_KEYWORD \ __cplusplus \ - Q_COMPILER_INITIALIZER_LISTS + Q_COMPILER_INITIALIZER_LISTS \ + Q_COMPILER_RVALUE_REFS Cpp.ignoretokens += \ PHONON_EXPORT \ diff --git a/doc/global/template/style/offline.css b/doc/global/template/style/offline.css index f573633331..5dc4908aff 100644 --- a/doc/global/template/style/offline.css +++ b/doc/global/template/style/offline.css @@ -3,7 +3,7 @@ body { margin-top: 85px; font-family: Arial, Helvetica; color: #313131; - text-align: justify; + text-align: left; margin-left: 5px; margin-right: 5px; } @@ -38,7 +38,7 @@ img { margin-top: 35px; /*max-width: 75%;*/ margin-left: 5px; - text-align: justify; + text-align: left; vertical-align: top; } diff --git a/doc/global/template/style/online.css b/doc/global/template/style/online.css index cf73455877..d105a6fd55 100644 --- a/doc/global/template/style/online.css +++ b/doc/global/template/style/online.css @@ -24,7 +24,7 @@ img { margin-top: 35px; /*max-width: 75%;*/ margin-left: 5px; - text-align: justify; + text-align: left; vertical-align: top; } diff --git a/examples/widgets/widgets.pro b/examples/widgets/widgets.pro index 14acebc33f..693beb56f7 100644 --- a/examples/widgets/widgets.pro +++ b/examples/widgets/widgets.pro @@ -25,5 +25,6 @@ contains(QT_CONFIG, opengl(es1|es2)?) { SUBDIRS += windowcontainer } +!contains(QT_CONFIG, opengl(es1|es2)?): SUBDIRS -= windowcontainer contains(DEFINES, QT_NO_CURSOR): SUBDIRS -= mainwindows contains(DEFINES, QT_NO_DRAGANDDROP): SUBDIRS -= draganddrop diff --git a/mkspecs/blackberry-armv7le-qcc/qmake.conf b/mkspecs/blackberry-armv7le-qcc/qmake.conf index cfcd2aecf0..2e24e4e0d3 100644 --- a/mkspecs/blackberry-armv7le-qcc/qmake.conf +++ b/mkspecs/blackberry-armv7le-qcc/qmake.conf @@ -16,7 +16,6 @@ contains(QT_CONFIG, stack-protector-strong) { } QMAKE_CFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2 -QMAKE_CXXFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2 QMAKE_LFLAGS_SHLIB += -Wl,-z,relro -Wl,-z,now diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS index c1618ba057..dc89614e07 100644 --- a/src/3rdparty/harfbuzz-ng/NEWS +++ b/src/3rdparty/harfbuzz-ng/NEWS @@ -1,3 +1,51 @@ +Overview of changes leading to 0.9.20 +Thursday, August 29, 2013 +===================================== + +General: +- Misc substitute_closure() fixes. +- Build fixes. + +Documentation: +- gtk-doc boilerplate integrated. Docs are built now, but + contain no contents. By next release hopefully we have + some content in. Enable using --enable-gtk-doc. + +GObject and Introspection: +- Added harfbuzz-gobject library (hb-gobject.h) that has type + bindings for all HarfBuzz objects and enums. Enable using + --with-gobject. +- Added gobject-introspection boilerplate. Nothing useful + right now. Work in progress. Gets enabled automatically if + --with-gobject is used. Override with --disable-introspection. + +OpenType shaper: +- Apply 'mark' in Myanmar shaper. +- Don't apply 'dlig' by default. + +Uniscribe shaper: +- Support user features. +- Fix loading of fonts that are also installed on the system. +- Fix shaping of Arabic Presentation Forms. +- Fix build with wide chars. + +CoreText shaper: +- Support user features. + +Source changes: +- hb_face_t code moved to hb-face.h / hb-face.cc. +- Added hb-deprecated.h. + +API changes: +- Added HB_DISABLE_DEPRECATED. +- Deprecated HB_SCRIPT_CANADIAN_ABORIGINAL; replaced by + HB_SCRIPT_CANADIAN_SYLLABICS. +- Deprecated HB_BUFFER_FLAGS_DEFAULT; replaced by + HB_BUFFER_FLAG_DEFAULT. +- Deprecated HB_BUFFER_SERIALIZE_FLAGS_DEFAULT; replaced by + HB_BUFFER_SERIALIZE_FLAG_DEFAULT. + + Overview of changes leading to 0.9.19 Tuesday, July 16, 2013 ===================================== diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-deprecated.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-deprecated.h new file mode 100644 index 0000000000..8ac7eab8ea --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-deprecated.h @@ -0,0 +1 @@ +#include "../../src/hb-deprecated.h" diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-face.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-face.h new file mode 100644 index 0000000000..a38c4b29ba --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-face.h @@ -0,0 +1 @@ +#include "../../src/hb-face.h" diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb.h index 641fa370b0..d2e89d3443 100644 --- a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb.h +++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb.h @@ -1,9 +1 @@ -#include "hb-blob.h" -#include "hb-buffer.h" -#include "hb-common.h" -#include "hb-font.h" -#include "hb-set.h" -#include "hb-shape.h" -#include "hb-shape-plan.h" -#include "hb-unicode.h" -#include "hb-version.h" +#include "../../src/hb.h" diff --git a/src/3rdparty/harfbuzz-ng/src/config.h b/src/3rdparty/harfbuzz-ng/src/config.h index 62e42e54e4..fe9a450533 100644 --- a/src/3rdparty/harfbuzz-ng/src/config.h +++ b/src/3rdparty/harfbuzz-ng/src/config.h @@ -6,6 +6,8 @@ #define HB_NO_MT #define HB_NO_UNICODE_FUNCS +#define HB_DISABLE_DEPRECATED + #include <QtCore/qglobal.h> #ifndef HB_INTERNAL diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc index dc47ba73e0..eac69000dd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc @@ -100,10 +100,10 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, *p++ = '"'; } else - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint)); if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster)); } if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) @@ -161,21 +161,21 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, p += strlen (p); } else - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint)); if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster)); } if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { if (pos[i].x_offset || pos[i].y_offset) - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset)); *p++ = '+'; - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance)); if (pos->y_advance) - p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); } if (buf_size > (p - b)) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc index c0ca484f94..340bd5351b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc @@ -176,7 +176,7 @@ hb_buffer_t::clear (void) hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT; props = default_props; - flags = HB_BUFFER_FLAGS_DEFAULT; + flags = HB_BUFFER_FLAG_DEFAULT; content_type = HB_BUFFER_CONTENT_TYPE_INVALID; in_error = false; @@ -624,7 +624,7 @@ hb_buffer_get_empty (void) const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil), HB_SEGMENT_PROPERTIES_DEFAULT, - HB_BUFFER_FLAGS_DEFAULT, + HB_BUFFER_FLAG_DEFAULT, HB_BUFFER_CONTENT_TYPE_INVALID, true, /* in_error */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h index 55a4045719..87c4ce58e8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h @@ -171,8 +171,8 @@ void hb_buffer_guess_segment_properties (hb_buffer_t *buffer); -typedef enum { - HB_BUFFER_FLAGS_DEFAULT = 0x00000000, +typedef enum { /*< flags >*/ + HB_BUFFER_FLAG_DEFAULT = 0x00000000, HB_BUFFER_FLAG_BOT = 0x00000001, /* Beginning-of-text */ HB_BUFFER_FLAG_EOT = 0x00000002, /* End-of-text */ HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004 @@ -274,8 +274,8 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer); * Serialize */ -typedef enum { - HB_BUFFER_SERIALIZE_FLAGS_DEFAULT = 0x00000000, +typedef enum { /*< flags >*/ + HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000, HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001, HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002, HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004 diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h index 8699bf632e..9079b2c046 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h @@ -273,9 +273,6 @@ typedef enum /*---*/ HB_SCRIPT_INVALID = HB_TAG_NONE } hb_script_t; -/* Deprecated misspellings. */ -#define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS - /* These are moved out of hb_script_t because glib-mkenums chokes otherwise. */ #if 0 /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), diff --git a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h new file mode 100644 index 0000000000..30ae4b1caf --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h @@ -0,0 +1,51 @@ +/* + * Copyright © 2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_H_IN +#error "Include <hb.h> instead." +#endif + +#ifndef HB_DEPRECATED_H +#define HB_DEPRECATED_H + +#include "hb-common.h" +#include "hb-unicode.h" +#include "hb-font.h" + +HB_BEGIN_DECLS + +#ifndef HB_DISABLE_DEPRECATED + +#define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS + +#define HB_BUFFER_FLAGS_DEFAULT HB_BUFFER_FLAG_DEFAULT +#define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT HB_BUFFER_SERIALIZE_FLAG_DEFAULT + +#endif + +HB_END_DECLS + +#endif /* HB_DEPRECATED_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh new file mode 100644 index 0000000000..b33be0e5fc --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh @@ -0,0 +1,108 @@ +/* + * Copyright © 2009 Red Hat, Inc. + * Copyright © 2011 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_FACE_PRIVATE_HH +#define HB_FACE_PRIVATE_HH + +#include "hb-private.hh" + +#include "hb-font.h" +#include "hb-object-private.hh" +#include "hb-shaper-private.hh" +#include "hb-shape-plan-private.hh" + + +/* + * hb_face_t + */ + +struct hb_face_t { + hb_object_header_t header; + ASSERT_POD (); + + hb_bool_t immutable; + + hb_reference_table_func_t reference_table_func; + void *user_data; + hb_destroy_func_t destroy; + + unsigned int index; + mutable unsigned int upem; + mutable unsigned int num_glyphs; + + struct hb_shaper_data_t shaper_data; + + struct plan_node_t { + hb_shape_plan_t *shape_plan; + plan_node_t *next; + } *shape_plans; + + + inline hb_blob_t *reference_table (hb_tag_t tag) const + { + hb_blob_t *blob; + + if (unlikely (!this || !reference_table_func)) + return hb_blob_get_empty (); + + blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data); + if (unlikely (!blob)) + return hb_blob_get_empty (); + + return blob; + } + + inline HB_PURE_FUNC unsigned int get_upem (void) const + { + if (unlikely (!upem)) + load_upem (); + return upem; + } + + inline unsigned int get_num_glyphs (void) const + { + if (unlikely (num_glyphs == (unsigned int) -1)) + load_num_glyphs (); + return num_glyphs; + } + + private: + HB_INTERNAL void load_upem (void) const; + HB_INTERNAL void load_num_glyphs (void) const; +}; + +extern HB_INTERNAL const hb_face_t _hb_face_nil; + +#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS +#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face); +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT +#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS + + +#endif /* HB_FACE_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc new file mode 100644 index 0000000000..d8b9ed8c3f --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc @@ -0,0 +1,311 @@ +/* + * Copyright © 2009 Red Hat, Inc. + * Copyright © 2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-private.hh" + +#include "hb-ot-layout-private.hh" + +#include "hb-font-private.hh" +#include "hb-blob.h" +#include "hb-open-file-private.hh" +#include "hb-ot-head-table.hh" +#include "hb-ot-maxp-table.hh" + +#include "hb-cache-private.hh" + +#include <string.h> + + +/* + * hb_face_t + */ + +const hb_face_t _hb_face_nil = { + HB_OBJECT_HEADER_STATIC, + + true, /* immutable */ + + NULL, /* reference_table_func */ + NULL, /* user_data */ + NULL, /* destroy */ + + 0, /* index */ + 1000, /* upem */ + 0, /* num_glyphs */ + + { +#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + }, + + NULL, /* shape_plans */ +}; + + +hb_face_t * +hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, + void *user_data, + hb_destroy_func_t destroy) +{ + hb_face_t *face; + + if (!reference_table_func || !(face = hb_object_create<hb_face_t> ())) { + if (destroy) + destroy (user_data); + return hb_face_get_empty (); + } + + face->reference_table_func = reference_table_func; + face->user_data = user_data; + face->destroy = destroy; + + face->upem = 0; + face->num_glyphs = (unsigned int) -1; + + return face; +} + + +typedef struct hb_face_for_data_closure_t { + hb_blob_t *blob; + unsigned int index; +} hb_face_for_data_closure_t; + +static hb_face_for_data_closure_t * +_hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) +{ + hb_face_for_data_closure_t *closure; + + closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t)); + if (unlikely (!closure)) + return NULL; + + closure->blob = blob; + closure->index = index; + + return closure; +} + +static void +_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) +{ + hb_blob_destroy (closure->blob); + free (closure); +} + +static hb_blob_t * +_hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) +{ + hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; + + if (tag == HB_TAG_NONE) + return hb_blob_reference (data->blob); + + const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob); + const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); + + const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag); + + hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length); + + return blob; +} + +hb_face_t * +hb_face_create (hb_blob_t *blob, + unsigned int index) +{ + hb_face_t *face; + + if (unlikely (!blob || !hb_blob_get_length (blob))) + return hb_face_get_empty (); + + hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); + + if (unlikely (!closure)) + return hb_face_get_empty (); + + face = hb_face_create_for_tables (_hb_face_for_data_reference_table, + closure, + (hb_destroy_func_t) _hb_face_for_data_closure_destroy); + + hb_face_set_index (face, index); + + return face; +} + +hb_face_t * +hb_face_get_empty (void) +{ + return const_cast<hb_face_t *> (&_hb_face_nil); +} + + +hb_face_t * +hb_face_reference (hb_face_t *face) +{ + return hb_object_reference (face); +} + +void +hb_face_destroy (hb_face_t *face) +{ + if (!hb_object_destroy (face)) return; + + for (hb_face_t::plan_node_t *node = face->shape_plans; node; ) + { + hb_face_t::plan_node_t *next = node->next; + hb_shape_plan_destroy (node->shape_plan); + free (node); + node = next; + } + +#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face); +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + + if (face->destroy) + face->destroy (face->user_data); + + free (face); +} + +hb_bool_t +hb_face_set_user_data (hb_face_t *face, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace) +{ + return hb_object_set_user_data (face, key, data, destroy, replace); +} + +void * +hb_face_get_user_data (hb_face_t *face, + hb_user_data_key_t *key) +{ + return hb_object_get_user_data (face, key); +} + +void +hb_face_make_immutable (hb_face_t *face) +{ + if (hb_object_is_inert (face)) + return; + + face->immutable = true; +} + +hb_bool_t +hb_face_is_immutable (hb_face_t *face) +{ + return face->immutable; +} + + +hb_blob_t * +hb_face_reference_table (hb_face_t *face, + hb_tag_t tag) +{ + return face->reference_table (tag); +} + +hb_blob_t * +hb_face_reference_blob (hb_face_t *face) +{ + return face->reference_table (HB_TAG_NONE); +} + +void +hb_face_set_index (hb_face_t *face, + unsigned int index) +{ + if (hb_object_is_inert (face)) + return; + + face->index = index; +} + +unsigned int +hb_face_get_index (hb_face_t *face) +{ + return face->index; +} + +void +hb_face_set_upem (hb_face_t *face, + unsigned int upem) +{ + if (hb_object_is_inert (face)) + return; + + face->upem = upem; +} + +unsigned int +hb_face_get_upem (hb_face_t *face) +{ + return face->get_upem (); +} + +void +hb_face_t::load_upem (void) const +{ + hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head)); + const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob); + upem = head_table->get_upem (); + hb_blob_destroy (head_blob); +} + +void +hb_face_set_glyph_count (hb_face_t *face, + unsigned int glyph_count) +{ + if (hb_object_is_inert (face)) + return; + + face->num_glyphs = glyph_count; +} + +unsigned int +hb_face_get_glyph_count (hb_face_t *face) +{ + return face->get_num_glyphs (); +} + +void +hb_face_t::load_num_glyphs (void) const +{ + hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp)); + const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob); + num_glyphs = maxp_table->get_num_glyphs (); + hb_blob_destroy (maxp_blob); +} + + diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.h b/src/3rdparty/harfbuzz-ng/src/hb-face.h new file mode 100644 index 0000000000..f682c468de --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.h @@ -0,0 +1,117 @@ +/* + * Copyright © 2009 Red Hat, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + */ + +#ifndef HB_H_IN +#error "Include <hb.h> instead." +#endif + +#ifndef HB_FACE_H +#define HB_FACE_H + +#include "hb-common.h" +#include "hb-blob.h" + +HB_BEGIN_DECLS + + +/* + * hb_face_t + */ + +typedef struct hb_face_t hb_face_t; + +hb_face_t * +hb_face_create (hb_blob_t *blob, + unsigned int index); + +typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data); + +/* calls destroy() when not needing user_data anymore */ +hb_face_t * +hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, + void *user_data, + hb_destroy_func_t destroy); + +hb_face_t * +hb_face_get_empty (void); + +hb_face_t * +hb_face_reference (hb_face_t *face); + +void +hb_face_destroy (hb_face_t *face); + +hb_bool_t +hb_face_set_user_data (hb_face_t *face, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace); + + +void * +hb_face_get_user_data (hb_face_t *face, + hb_user_data_key_t *key); + +void +hb_face_make_immutable (hb_face_t *face); + +hb_bool_t +hb_face_is_immutable (hb_face_t *face); + + +hb_blob_t * +hb_face_reference_table (hb_face_t *face, + hb_tag_t tag); + +hb_blob_t * +hb_face_reference_blob (hb_face_t *face); + +void +hb_face_set_index (hb_face_t *face, + unsigned int index); + +unsigned int +hb_face_get_index (hb_face_t *face); + +void +hb_face_set_upem (hb_face_t *face, + unsigned int upem); + +unsigned int +hb_face_get_upem (hb_face_t *face); + +void +hb_face_set_glyph_count (hb_face_t *face, + unsigned int glyph_count); + +unsigned int +hb_face_get_glyph_count (hb_face_t *face); + + +HB_END_DECLS + +#endif /* HB_FACE_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh index acea1d724e..620d05e8f9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh @@ -33,8 +33,8 @@ #include "hb-font.h" #include "hb-object-private.hh" +#include "hb-face-private.hh" #include "hb-shaper-private.hh" -#include "hb-shape-plan-private.hh" @@ -84,71 +84,6 @@ struct hb_font_funcs_t { }; -/* - * hb_face_t - */ - -struct hb_face_t { - hb_object_header_t header; - ASSERT_POD (); - - hb_bool_t immutable; - - hb_reference_table_func_t reference_table_func; - void *user_data; - hb_destroy_func_t destroy; - - unsigned int index; - mutable unsigned int upem; - mutable unsigned int num_glyphs; - - struct hb_shaper_data_t shaper_data; - - struct plan_node_t { - hb_shape_plan_t *shape_plan; - plan_node_t *next; - } *shape_plans; - - - inline hb_blob_t *reference_table (hb_tag_t tag) const - { - hb_blob_t *blob; - - if (unlikely (!this || !reference_table_func)) - return hb_blob_get_empty (); - - blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data); - if (unlikely (!blob)) - return hb_blob_get_empty (); - - return blob; - } - - inline HB_PURE_FUNC unsigned int get_upem (void) const - { - if (unlikely (!upem)) - load_upem (); - return upem; - } - - inline unsigned int get_num_glyphs (void) const - { - if (unlikely (num_glyphs == (unsigned int) -1)) - load_num_glyphs (); - return num_glyphs; - } - - private: - HB_INTERNAL void load_upem (void) const; - HB_INTERNAL void load_num_glyphs (void) const; -}; - -#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face); -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT -#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS - /* * hb_font_t @@ -426,7 +361,8 @@ struct hb_font_t { { if (get_glyph_name (glyph, s, size)) return; - snprintf (s, size, "gid%u", glyph); + if (size && snprintf (s, size, "gid%u", glyph) < 0) + *s = '\0'; } /* Parses gidDDD and uniUUUU strings automatically. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc index b59fdebaea..c2f6f6ddd5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc @@ -41,7 +41,6 @@ #include <string.h> - /* * hb_font_funcs_t */ @@ -507,274 +506,6 @@ hb_font_glyph_from_string (hb_font_t *font, /* - * hb_face_t - */ - -static const hb_face_t _hb_face_nil = { - HB_OBJECT_HEADER_STATIC, - - true, /* immutable */ - - NULL, /* reference_table_func */ - NULL, /* user_data */ - NULL, /* destroy */ - - 0, /* index */ - 1000, /* upem */ - 0, /* num_glyphs */ - - { -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - }, - - NULL, /* shape_plans */ -}; - - -hb_face_t * -hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, - void *user_data, - hb_destroy_func_t destroy) -{ - hb_face_t *face; - - if (!reference_table_func || !(face = hb_object_create<hb_face_t> ())) { - if (destroy) - destroy (user_data); - return hb_face_get_empty (); - } - - face->reference_table_func = reference_table_func; - face->user_data = user_data; - face->destroy = destroy; - - face->upem = 0; - face->num_glyphs = (unsigned int) -1; - - return face; -} - - -typedef struct hb_face_for_data_closure_t { - hb_blob_t *blob; - unsigned int index; -} hb_face_for_data_closure_t; - -static hb_face_for_data_closure_t * -_hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) -{ - hb_face_for_data_closure_t *closure; - - closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t)); - if (unlikely (!closure)) - return NULL; - - closure->blob = blob; - closure->index = index; - - return closure; -} - -static void -_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) -{ - hb_blob_destroy (closure->blob); - free (closure); -} - -static hb_blob_t * -_hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) -{ - hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; - - if (tag == HB_TAG_NONE) - return hb_blob_reference (data->blob); - - const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob); - const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); - - const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag); - - hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length); - - return blob; -} - -hb_face_t * -hb_face_create (hb_blob_t *blob, - unsigned int index) -{ - hb_face_t *face; - - if (unlikely (!blob || !hb_blob_get_length (blob))) - return hb_face_get_empty (); - - hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); - - if (unlikely (!closure)) - return hb_face_get_empty (); - - face = hb_face_create_for_tables (_hb_face_for_data_reference_table, - closure, - (hb_destroy_func_t) _hb_face_for_data_closure_destroy); - - hb_face_set_index (face, index); - - return face; -} - -hb_face_t * -hb_face_get_empty (void) -{ - return const_cast<hb_face_t *> (&_hb_face_nil); -} - - -hb_face_t * -hb_face_reference (hb_face_t *face) -{ - return hb_object_reference (face); -} - -void -hb_face_destroy (hb_face_t *face) -{ - if (!hb_object_destroy (face)) return; - - for (hb_face_t::plan_node_t *node = face->shape_plans; node; ) - { - hb_face_t::plan_node_t *next = node->next; - hb_shape_plan_destroy (node->shape_plan); - free (node); - node = next; - } - -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face); -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - - if (face->destroy) - face->destroy (face->user_data); - - free (face); -} - -hb_bool_t -hb_face_set_user_data (hb_face_t *face, - hb_user_data_key_t *key, - void * data, - hb_destroy_func_t destroy, - hb_bool_t replace) -{ - return hb_object_set_user_data (face, key, data, destroy, replace); -} - -void * -hb_face_get_user_data (hb_face_t *face, - hb_user_data_key_t *key) -{ - return hb_object_get_user_data (face, key); -} - -void -hb_face_make_immutable (hb_face_t *face) -{ - if (hb_object_is_inert (face)) - return; - - face->immutable = true; -} - -hb_bool_t -hb_face_is_immutable (hb_face_t *face) -{ - return face->immutable; -} - - -hb_blob_t * -hb_face_reference_table (hb_face_t *face, - hb_tag_t tag) -{ - return face->reference_table (tag); -} - -hb_blob_t * -hb_face_reference_blob (hb_face_t *face) -{ - return face->reference_table (HB_TAG_NONE); -} - -void -hb_face_set_index (hb_face_t *face, - unsigned int index) -{ - if (hb_object_is_inert (face)) - return; - - face->index = index; -} - -unsigned int -hb_face_get_index (hb_face_t *face) -{ - return face->index; -} - -void -hb_face_set_upem (hb_face_t *face, - unsigned int upem) -{ - if (hb_object_is_inert (face)) - return; - - face->upem = upem; -} - -unsigned int -hb_face_get_upem (hb_face_t *face) -{ - return face->get_upem (); -} - -void -hb_face_t::load_upem (void) const -{ - hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head)); - const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob); - upem = head_table->get_upem (); - hb_blob_destroy (head_blob); -} - -void -hb_face_set_glyph_count (hb_face_t *face, - unsigned int glyph_count) -{ - if (hb_object_is_inert (face)) - return; - - face->num_glyphs = glyph_count; -} - -unsigned int -hb_face_get_glyph_count (hb_face_t *face) -{ - return face->get_num_glyphs (); -} - -void -hb_face_t::load_num_glyphs (void) const -{ - hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp)); - const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob); - num_glyphs = maxp_table->get_num_glyphs (); - hb_blob_destroy (maxp_blob); -} - - -/* * hb_font_t */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h index 88d489551e..3a0c001b98 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h @@ -32,86 +32,13 @@ #define HB_FONT_H #include "hb-common.h" -#include "hb-blob.h" +#include "hb-face.h" HB_BEGIN_DECLS -typedef struct hb_face_t hb_face_t; typedef struct hb_font_t hb_font_t; -/* - * hb_face_t - */ - -hb_face_t * -hb_face_create (hb_blob_t *blob, - unsigned int index); - -typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data); - -/* calls destroy() when not needing user_data anymore */ -hb_face_t * -hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, - void *user_data, - hb_destroy_func_t destroy); - -hb_face_t * -hb_face_get_empty (void); - -hb_face_t * -hb_face_reference (hb_face_t *face); - -void -hb_face_destroy (hb_face_t *face); - -hb_bool_t -hb_face_set_user_data (hb_face_t *face, - hb_user_data_key_t *key, - void * data, - hb_destroy_func_t destroy, - hb_bool_t replace); - - -void * -hb_face_get_user_data (hb_face_t *face, - hb_user_data_key_t *key); - -void -hb_face_make_immutable (hb_face_t *face); - -hb_bool_t -hb_face_is_immutable (hb_face_t *face); - - -hb_blob_t * -hb_face_reference_table (hb_face_t *face, - hb_tag_t tag); - -hb_blob_t * -hb_face_reference_blob (hb_face_t *face); - -void -hb_face_set_index (hb_face_t *face, - unsigned int index); - -unsigned int -hb_face_get_index (hb_face_t *face); - -void -hb_face_set_upem (hb_face_t *face, - unsigned int upem); - -unsigned int -hb_face_get_upem (hb_face_t *face); - -void -hb_face_set_glyph_count (hb_face_t *face, - unsigned int glyph_count); - -unsigned int -hb_face_get_glyph_count (hb_face_t *face); - /* * hb_font_funcs_t diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc index c28fdfa254..80d8c1306b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc @@ -181,18 +181,18 @@ hb_feature_to_string (hb_feature_t *feature, { s[len++] = '['; if (feature->start) - len += snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->start); + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->start)); if (feature->end != feature->start + 1) { s[len++] = ':'; if (feature->end != (unsigned int) -1) - len += snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->end); + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->end)); } s[len++] = ']'; } if (feature->value > 1) { s[len++] = '='; - len += snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->value); + len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->value)); } assert (len < ARRAY_LENGTH (s)); len = MIN (len, size - 1); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h index 5a7180f6f3..dc07ef794a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h @@ -38,9 +38,9 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 0 #define HB_VERSION_MINOR 9 -#define HB_VERSION_MICRO 19 +#define HB_VERSION_MICRO 20 -#define HB_VERSION_STRING "0.9.19" +#define HB_VERSION_STRING "0.9.20" #define HB_VERSION_CHECK(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) >= \ diff --git a/src/3rdparty/harfbuzz-ng/src/hb.h b/src/3rdparty/harfbuzz-ng/src/hb.h index 52c479cc2e..c5a938a381 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb.h +++ b/src/3rdparty/harfbuzz-ng/src/hb.h @@ -31,6 +31,8 @@ #include "hb-blob.h" #include "hb-buffer.h" #include "hb-common.h" +#include "hb-deprecated.h" +#include "hb-face.h" #include "hb-font.h" #include "hb-set.h" #include "hb-shape.h" diff --git a/src/3rdparty/harfbuzz.pri b/src/3rdparty/harfbuzz.pri index fd0750ae1a..bc8d49c625 100644 --- a/src/3rdparty/harfbuzz.pri +++ b/src/3rdparty/harfbuzz.pri @@ -8,6 +8,7 @@ contains(QT_CONFIG, harfbuzz) { $$QT_HARFBUZZ_DIR/src/hb-buffer.cc \ $$QT_HARFBUZZ_DIR/src/hb-buffer-serialize.cc \ $$QT_HARFBUZZ_DIR/src/hb-common.cc \ + $$QT_HARFBUZZ_DIR/src/hb-face.cc \ $$QT_HARFBUZZ_DIR/src/hb-fallback-shape.cc \ $$QT_HARFBUZZ_DIR/src/hb-font.cc \ $$QT_HARFBUZZ_DIR/src/hb-ot-tag.cc \ @@ -24,6 +25,7 @@ contains(QT_CONFIG, harfbuzz) { $$QT_HARFBUZZ_DIR/src/hb-buffer-deserialize-json.hh \ $$QT_HARFBUZZ_DIR/src/hb-buffer-deserialize-text.hh \ $$QT_HARFBUZZ_DIR/src/hb-cache-private.hh \ + $$QT_HARFBUZZ_DIR/src/hb-face-private.hh \ $$QT_HARFBUZZ_DIR/src/hb-font-private.hh \ $$QT_HARFBUZZ_DIR/src/hb-mutex-private.hh \ $$QT_HARFBUZZ_DIR/src/hb-object-private.hh \ @@ -48,6 +50,7 @@ contains(QT_CONFIG, harfbuzz) { $$QT_HARFBUZZ_DIR/src/hb-blob.h \ $$QT_HARFBUZZ_DIR/src/hb-buffer.h \ $$QT_HARFBUZZ_DIR/src/hb-common.h \ + $$QT_HARFBUZZ_DIR/src/hb-face.h \ $$QT_HARFBUZZ_DIR/src/hb-font.h \ $$QT_HARFBUZZ_DIR/src/hb-set.h \ $$QT_HARFBUZZ_DIR/src/hb-shape.h \ diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 8d67db7f40..8dc804cce4 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -160,6 +160,12 @@ public class QtActivityDelegate private final int ImhEmailCharactersOnly = 0x200000; private final int ImhUrlCharactersOnly = 0x400000; + // application state + private final int ApplicationSuspended = 0x0; + private final int ApplicationHidden = 0x1; + private final int ApplicationInactive = 0x2; + private final int ApplicationActive = 0x4; + public void resetSoftwareKeyboard() { if (m_imm == null) @@ -621,6 +627,11 @@ public class QtActivityDelegate m_surface.applicationStarted(true); } + public void onPause() + { + QtNative.updateApplicationState(ApplicationInactive); + } + public void onResume() { // fire all lostActions @@ -631,12 +642,18 @@ public class QtActivityDelegate m_activity.runOnUiThread(itr.next()); if (m_started) { + QtNative.updateApplicationState(ApplicationActive); QtNative.clearLostActions(); QtNative.updateWindow(); } } } + public void onStop() + { + QtNative.updateApplicationState(ApplicationSuspended); + } + public Object onRetainNonConfigurationInstance() { try { diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 122fc55aad..51f00a73c6 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -582,6 +582,9 @@ public class QtNative public static native void updateWindow(); // window methods + // application methods + public static native void updateApplicationState(int state); + // menu methods public static native boolean onPrepareOptionsMenu(Menu menu); public static native boolean onOptionsItemSelected(int itemId, boolean checked); diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index 52b80badb8..008460df5d 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -539,8 +539,8 @@ void QDataStream::setByteOrder(ByteOrder bo) \value Qt_4_8 Same as Qt_4_6. \value Qt_4_9 Same as Qt_4_6. \value Qt_5_0 Version 13 (Qt 5.0) - \value Qt_5_1 Version 14 (Qt 5.1, Qt 5.2) - \value Qt_5_2 Same as Qt_5_1. + \value Qt_5_1 Version 14 (Qt 5.1) + \value Qt_5_2 Version 15 (Qt 5.2) \sa setVersion(), version() */ @@ -572,6 +572,7 @@ void QDataStream::setByteOrder(ByteOrder bo) \table \header \li Qt Version \li QDataStream Version + \row \li Qt 5.2 \li 15 \row \li Qt 5.1 \li 14 \row \li Qt 5.0 \li 13 \row \li Qt 4.6 \li 12 diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h index eb064b3fe2..f107e801b6 100644 --- a/src/corelib/io/qdatastream.h +++ b/src/corelib/io/qdatastream.h @@ -87,7 +87,7 @@ public: Qt_4_9 = Qt_4_8, Qt_5_0 = 13, Qt_5_1 = 14, - Qt_5_2 = Qt_5_1 + Qt_5_2 = 15 #if QT_VERSION >= 0x050300 #error Add the datastream version for this Qt version #endif diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 96cec568df..d473281acc 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1317,6 +1317,10 @@ void QProcess::closeWriteChannel() object will be in read-only mode (calling write() will result in error). + To make the process read EOF right away, pass nullDevice() here. + This is cleaner than using closeWriteChannel() before writing any + data, because it can be set up prior to starting the process. + If the file \a fileName does not exist at the moment start() is called or is not readable, starting the process will fail. @@ -1340,6 +1344,10 @@ void QProcess::setStandardInputFile(const QString &fileName) read channel is closed: reading from it using read() will always fail, as will readAllStandardOutput(). + To discard all standard output from the process, pass nullDevice() + here. This is more efficient than simply never reading the standard + output, as no QProcess buffers are filled. + If the file \a fileName doesn't exist at the moment start() is called, it will be created. If it cannot be created, the starting will fail. @@ -2440,6 +2448,25 @@ QStringList QProcess::systemEnvironment() */ /*! + \since 5.2 + + \brief The null device of the operating system. + + The returned file path uses native directory separators. + + \sa QProcess::setStandardInputFile(), QProcess::setStandardOutputFile(), + QProcess::setStandardErrorFile() +*/ +QString QProcess::nullDevice() +{ +#ifdef Q_OS_WIN + return QStringLiteral("\\\\.\\NUL"); +#else + return QStringLiteral("/dev/null"); +#endif +} + +/*! \typedef Q_PID \relates QProcess diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index 9da3e63f38..2919788e34 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -209,6 +209,8 @@ public: static QStringList systemEnvironment(); + static QString nullDevice(); + public Q_SLOTS: void terminate(); void kill(); diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index 54c1ff8843..fb60534495 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -117,20 +117,33 @@ QT_BEGIN_NAMESPACE \sa isEmpty() */ +/* + * QBitArray construction note: + * + * We overallocate the byte array by 1 byte. The first user bit is at + * d.data()[1]. On the extra first byte, we store the difference between the + * number of bits in the byte array (including this byte) and the number of + * bits in the bit array. Therefore, it's always a number between 8 and 15. + * + * This allows for fast calculation of the bit array size: + * inline int size() const { return (d.size() << 3) - *d.constData(); } + * + * Note: for an array of zero size, *d.constData() is the QByteArray implicit NUL. + */ + /*! Constructs a bit array containing \a size bits. The bits are initialized with \a value, which defaults to false (0). */ QBitArray::QBitArray(int size, bool value) + : d(size <= 0 ? 0 : 1 + (size + 7)/8, Qt::Uninitialized) { Q_ASSERT_X(size >= 0, "QBitArray::QBitArray", "Size must be greater than or equal to 0."); - if (size <= 0) { - d.resize(0); + if (size <= 0) return; - } - d.resize(1 + (size+7)/8); + uchar* c = reinterpret_cast<uchar*>(d.data()); - memset(c, value ? 0xff : 0, d.size()); + memset(c + 1, value ? 0xff : 0, d.size() - 1); *c = d.size()*8 - size; if (value && size && size % 8) *(c+1+size/8) &= (1 << (size%8)) - 1; @@ -174,10 +187,10 @@ int QBitArray::count(bool on) const bits += 3; numBits += int(qPopulationCount(v)); } - while (len >= 0) { - if (bits[len / 8] & (1 << ((len - 1) & 7))) - ++numBits; + while (len > 0) { --len; + if (bits[len / 8] & (1 << (len & 7))) + ++numBits; } #endif return on ? numBits : size() - numBits; diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index b47511c39c..008e72af1c 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -172,6 +172,58 @@ int qt_monthNumberFromShortName(const QString &shortName) static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0); static void rfcDateImpl(const QString &s, QDate *dd = 0, QTime *dt = 0, int *utfcOffset = 0); #endif +static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time); +static void utcToOffset(QDate *date, QTime *time, qint32 offset); + +// Return offset in [+-]HH:MM format +// Qt::ISODate puts : between the hours and minutes, but Qt:TextDate does not +static QString toOffsetString(Qt::DateFormat format, int offset) +{ + QString result; + if (format == Qt::TextDate) + result = QStringLiteral("%1%2%3"); + else // Qt::ISODate + result = QStringLiteral("%1%2:%3"); + + return result.arg(offset >= 0 ? QLatin1Char('+') : QLatin1Char('-')) + .arg(qAbs(offset) / SECS_PER_HOUR, 2, 10, QLatin1Char('0')) + .arg((offset / 60) % 60, 2, 10, QLatin1Char('0')); +} + +// Parse offset in [+-]HH[:]MM format +static int fromOffsetString(const QString &offsetString, bool *valid) +{ + *valid = false; + + const int size = offsetString.size(); + if (size < 2 || size > 6) + return 0; + + // First char must be + or - + const QChar sign = offsetString.at(0); + if (sign != QLatin1Char('+') && sign != QLatin1Char('-')) + return 0; + + // Split the hour and minute parts + QStringList parts = offsetString.split(QLatin1Char(':')); + if (parts.count() == 1) { + // [+-]HHMM format + parts.append(parts.at(0).mid(3)); + parts[0] = parts.at(0).left(3); + } + + bool ok = false; + const int hour = parts.at(0).toInt(&ok); + if (!ok) + return 0; + + const int minute = parts.at(1).toInt(&ok); + if (!ok || minute < 0 || minute > 59) + return 0; + + *valid = true; + return ((hour * 60) + minute) * 60; +} /***************************************************************************** QDate member functions @@ -2165,6 +2217,20 @@ int QTime::elapsed() const time zone before 1970, even if the system's time zone database supports that information. + \section2 Offset From UTC + + A Qt::TimeSpec of Qt::OffsetFromUTC is also supported. This allows you + to define a QDateTime relative to UTC at a fixed offset of a given number + of seconds from UTC. For example, an offset of +3600 seconds is one hour + ahead of UTC and is usually written in ISO standard notation as + "UTC+01:00". Daylight Savings Time never applies with this TimeSpec. + + There is no explicit size restriction to the offset seconds, but there is + an implicit limit imposed when using the toString() and fromString() + methods which use a format of [+|-]hh:mm, effectively limiting the range + to +/- 99 hours and 59 minutes and whole minutes only. Note that currently + no time zone lies outside the range of +/- 14 hours. + \sa QDate, QTime, QDateTimeEdit */ @@ -2186,10 +2252,8 @@ QDateTime::QDateTime() */ QDateTime::QDateTime(const QDate &date) - : d(new QDateTimePrivate) + : d(new QDateTimePrivate(date, QTime(0, 0, 0), Qt::LocalTime, 0)) { - d->date = date; - d->time = QTime(0, 0, 0); } /*! @@ -2197,14 +2261,72 @@ QDateTime::QDateTime(const QDate &date) the time specification defined by \a spec. If \a date is valid and \a time is not, the time will be set to midnight. + + If \a spec is Qt::OffsetFromUTC then it will be set to Qt::UTC, i.e. an + offset of 0 seconds. To create a Qt::OffsetFromUTC datetime use the + correct constructor. */ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec) - : d(new QDateTimePrivate) + : d(new QDateTimePrivate(date, time, spec, 0)) { - d->date = date; - d->time = date.isValid() && !time.isValid() ? QTime(0, 0, 0) : time; - d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown; +} + +/*! + \since 5.2 + + Constructs a datetime with the given \a date and \a time, using + the time specification defined by \a spec and \a offsetSeconds seconds. + + If \a date is valid and \a time is not, the time will be set to midnight. + + If the \a spec is not Qt::OffsetFromUTC then \a offsetSeconds will be ignored. + + If the \a spec is Qt::OffsetFromUTC and \a offsetSeconds is 0 then the + timeSpec() will be set to Qt::UTC, i.e. an offset of 0 seconds. +*/ + +QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds) + : d(new QDateTimePrivate(date, time, spec, offsetSeconds)) +{ +} + +/*! + \internal + \since 5.2 + + Private. + + Create a datetime with the given \a date, \a time, \a spec and \a offsetSeconds +*/ + +QDateTimePrivate::QDateTimePrivate(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec, + int offsetSeconds) +{ + date = toDate; + + if (!toTime.isValid() && toDate.isValid()) + time = QTime(0, 0, 0); + else + time = toTime; + + m_offsetFromUtc = 0; + + switch (toSpec) { + case Qt::UTC : + spec = QDateTimePrivate::UTC; + break; + case Qt::OffsetFromUTC : + if (offsetSeconds == 0) { + spec = QDateTimePrivate::UTC; + } else { + spec = QDateTimePrivate::OffsetFromUTC; + m_offsetFromUtc = offsetSeconds; + } + break; + case Qt::LocalTime : + spec = QDateTimePrivate::LocalUnknown; + } } /*! @@ -2307,6 +2429,34 @@ Qt::TimeSpec QDateTime::timeSpec() const } /*! + \since 5.2 + + Returns the current Offset From UTC in seconds. + + If the timeSpec() is Qt::OffsetFromUTC this will be the value originally set. + + If the timeSpec() is Qt::LocalTime this will be the difference between the + Local Time and UTC including any Daylight Saving Offset. + + If the timeSpec() is Qt::UTC this will be 0. + + \sa setOffsetFromUtc() +*/ + +int QDateTime::offsetFromUtc() const +{ + switch (d->spec) { + case QDateTimePrivate::OffsetFromUTC: + return d->m_offsetFromUtc; + case QDateTimePrivate::UTC: + return 0; + default: // Any Qt::LocalTime + const QDateTime fakeDate(d->date, d->time, Qt::UTC); + return (fakeDate.toMSecsSinceEpoch() - toMSecsSinceEpoch()) / 1000; + } +} + +/*! Sets the date part of this datetime to \a date. If no time is set, it is set to midnight. @@ -2343,6 +2493,9 @@ void QDateTime::setTime(const QTime &time) Sets the time specification used in this datetime to \a spec. The datetime will refer to a different point in time. + If \a spec is Qt::OffsetFromUTC then the timeSpec() will be set + to Qt::UTC, i.e. an effective offset of 0. + Example: \snippet code/src_corelib_tools_qdatetime.cpp 19 @@ -2353,17 +2506,43 @@ void QDateTime::setTimeSpec(Qt::TimeSpec spec) { detach(); - switch(spec) - { - case Qt::UTC: - d->spec = QDateTimePrivate::UTC; - break; - case Qt::OffsetFromUTC: - d->spec = QDateTimePrivate::OffsetFromUTC; - break; - default: - d->spec = QDateTimePrivate::LocalUnknown; - break; + d->m_offsetFromUtc = 0; + switch (spec) { + case Qt::UTC: + case Qt::OffsetFromUTC: + d->spec = QDateTimePrivate::UTC; + break; + default: + d->spec = QDateTimePrivate::LocalUnknown; + break; + } +} + +/*! + \since 5.2 + + Sets the timeSpec() to Qt::OffsetFromUTC and the offset to \a offsetSeconds. + The datetime will refer to a different point in time. + + The maximum and minimum offset is 14 positive or negative hours. If + \a offsetSeconds is larger or smaller than that, then the result is + undefined. + + If \a offsetSeconds is 0 then the timeSpec() will be set to Qt::UTC. + + \sa isValid(), offsetFromUtc() +*/ + +void QDateTime::setOffsetFromUtc(int offsetSeconds) +{ + detach(); + + if (offsetSeconds == 0) { + d->spec = QDateTimePrivate::UTC; + d->m_offsetFromUtc = 0; + } else { + d->spec = QDateTimePrivate::OffsetFromUTC; + d->m_offsetFromUtc = offsetSeconds; } } @@ -2446,8 +2625,6 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) { detach(); - QDateTimePrivate::Spec oldSpec = d->spec; - qint64 ddays = msecs / MSECS_PER_DAY; msecs %= MSECS_PER_DAY; if (msecs < 0) { @@ -2458,10 +2635,11 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) d->date = QDate(1970, 1, 1).addDays(ddays); d->time = QTime(0, 0, 0).addMSecs(msecs); - d->spec = QDateTimePrivate::UTC; - if (oldSpec != QDateTimePrivate::UTC) - d->spec = d->getLocal(d->date, d->time); + if (d->spec == QDateTimePrivate::OffsetFromUTC) + utcToOffset(&d->date, &d->time, d->m_offsetFromUtc); + else if (d->spec != QDateTimePrivate::UTC) + utcToLocal(d->date, d->time); } /*! @@ -2479,14 +2657,13 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC) { detach(); - QDateTimePrivate::Spec oldSpec = d->spec; - d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY); d->time = QTime(0, 0, 0).addSecs(secsSince1Jan1970UTC % SECS_PER_DAY); - d->spec = QDateTimePrivate::UTC; - if (oldSpec != QDateTimePrivate::UTC) - d->spec = d->getLocal(d->date, d->time); + if (d->spec == QDateTimePrivate::OffsetFromUTC) + utcToOffset(&d->date, &d->time, d->m_offsetFromUtc); + else if (d->spec != QDateTimePrivate::UTC) + utcToLocal(d->date, d->time); } #ifndef QT_NO_DATESTRING @@ -2554,11 +2731,7 @@ QString QDateTime::toString(Qt::DateFormat f) const buf += QLatin1Char('Z'); break; case QDateTimePrivate::OffsetFromUTC: { - int sign = d->utcOffset >= 0 ? 1: -1; - buf += QString::fromLatin1("%1%2:%3"). - arg(sign == 1 ? QLatin1Char('+') : QLatin1Char('-')). - arg(d->utcOffset * sign / SECS_PER_HOUR, 2, 10, QLatin1Char('0')). - arg((d->utcOffset / 60) % 60, 2, 10, QLatin1Char('0')); + buf += toOffsetString(Qt::ISODate, d->m_offsetFromUtc); break; } default: @@ -2567,7 +2740,7 @@ QString QDateTime::toString(Qt::DateFormat f) const } else if (f == Qt::RFC2822Date) { buf = toString(QStringLiteral("dd MMM yyyy hh:mm:ss ")); - int utcOffset = d->utcOffset; + int utcOffset = d->m_offsetFromUtc; if (timeSpec() == Qt::LocalTime) { QDateTime utc = toUTC(); utc.setTimeSpec(timeSpec()); @@ -2762,10 +2935,13 @@ QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs) QDate utcDate; QTime utcTime; dt.d->getUTC(utcDate, utcTime); - addMSecs(utcDate, utcTime, msecs); + QDateTime utc(utcDate, utcTime, Qt::UTC); - return QDateTime(utcDate, utcTime, Qt::UTC).toTimeSpec(dt.timeSpec()); + if (dt.timeSpec() == Qt::OffsetFromUTC) + return utc.toOffsetFromUtc(dt.d->m_offsetFromUtc); + else + return utc.toTimeSpec(dt.timeSpec()); } /*! @@ -2916,12 +3092,14 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const + static_cast<qint64>(selfTime.msecsTo(otherTime)); } - /*! - \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec specification) const + \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const Returns a copy of this datetime converted to the given time - \a specification. + \a spec. + + If \a spec is Qt::OffsetFromUTC then it is set to Qt::UTC. To set to a + spec of Qt::OffsetFromUTC use toOffsetFromUtc(). Example: \snippet code/src_corelib_tools_qdatetime.cpp 16 @@ -2931,19 +3109,41 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const { - if ((d->spec == QDateTimePrivate::UTC) == (spec == Qt::UTC)) - return *this; + if (spec == Qt::UTC || spec == Qt::OffsetFromUTC) { + QDate date; + QTime time; + d->getUTC(date, time); + return QDateTime(date, time, Qt::UTC, 0); + } QDateTime ret; - if (spec == Qt::UTC) { - d->getUTC(ret.d->date, ret.d->time); - ret.d->spec = QDateTimePrivate::UTC; - } else { - ret.d->spec = d->getLocal(ret.d->date, ret.d->time); - } + ret.d->spec = d->getLocal(ret.d->date, ret.d->time); return ret; } + +/*! + \since 5.2 + + \fn QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const + + Returns a copy of this datetime converted to a spec of Qt::OffsetFromUTC + with the given \a offsetSeconds. + + If the \a offsetSeconds equals 0 then a UTC datetime will be returned + + \sa setOffsetFromUtc(), offsetFromUtc(), toTimeSpec() +*/ + +QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const +{ + QDate date; + QTime time; + d->getUTC(date, time); + d->addMSecs(date, time, offsetSeconds * 1000); + return QDateTime(date, time, Qt::OffsetFromUTC, offsetSeconds); +} + /*! Returns true if this datetime is equal to the \a other datetime; otherwise returns false. @@ -2953,7 +3153,7 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const bool QDateTime::operator==(const QDateTime &other) const { - if (d->spec == other.d->spec && d->utcOffset == other.d->utcOffset) + if (d->spec == other.d->spec && d->m_offsetFromUtc == other.d->m_offsetFromUtc) return d->time == other.d->time && d->date == other.d->date; else { QDate date1, date2; @@ -3230,16 +3430,32 @@ qint64 QDateTime::currentMSecsSinceEpoch() Q_DECL_NOTHROW Returns a datetime whose date and time are the number of \a seconds that have passed since 1970-01-01T00:00:00, Coordinated Universal - Time (Qt::UTC). On systems that do not support time zones, the time - will be set as if local time were Qt::UTC. + Time (Qt::UTC) and converted to Qt::LocalTime. On systems that do not + support time zones, the time will be set as if local time were Qt::UTC. \sa toTime_t(), setTime_t() */ QDateTime QDateTime::fromTime_t(uint seconds) { - QDateTime d; - d.setTime_t(seconds); - return d; + return fromMSecsSinceEpoch((qint64)seconds * 1000, Qt::LocalTime); +} + +/*! + \since 5.2 + + Returns a datetime whose date and time are the number of \a seconds + that have passed since 1970-01-01T00:00:00, Coordinated Universal + Time (Qt::UTC) and converted to the given \a spec. + + If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be + ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0 + then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds. + + \sa toTime_t(), setTime_t() +*/ +QDateTime QDateTime::fromTime_t(uint seconds, Qt::TimeSpec spec, int offsetSeconds) +{ + return fromMSecsSinceEpoch((qint64)seconds * 1000, spec, offsetSeconds); } /*! @@ -3247,8 +3463,8 @@ QDateTime QDateTime::fromTime_t(uint seconds) Returns a datetime whose date and time are the number of milliseconds, \a msecs, that have passed since 1970-01-01T00:00:00.000, Coordinated Universal - Time (Qt::UTC). On systems that do not support time zones, the time - will be set as if local time were Qt::UTC. + Time (Qt::UTC), and converted to Qt::LocalTime. On systems that do not + support time zones, the time will be set as if local time were Qt::UTC. Note that there are possible values for \a msecs that lie outside the valid range of QDateTime, both negative and positive. The behavior of this @@ -3258,67 +3474,79 @@ QDateTime QDateTime::fromTime_t(uint seconds) */ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs) { - QDateTime d; - d.setMSecsSinceEpoch(msecs); - return d; + return fromMSecsSinceEpoch(msecs, Qt::LocalTime); } /*! - \since 4.4 - \internal + \since 5.2 + + Returns a datetime whose date and time are the number of milliseconds \a msecs + that have passed since 1970-01-01T00:00:00.000, Coordinated Universal + Time (Qt::UTC) and converted to the given \a spec. - Sets the offset from UTC to \a seconds, and also sets timeSpec() to - Qt::OffsetFromUTC. + Note that there are possible values for \a msecs that lie outside the valid + range of QDateTime, both negative and positive. The behavior of this + function is undefined for those values. + + If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be + ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0 + then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds. + + \sa fromTime_t() +*/ +QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetSeconds) +{ + QDate newDate = QDate(1970, 1, 1); + QTime newTime = QTime(0, 0, 0); + QDateTimePrivate::addMSecs(newDate, newTime, msecs); - The maximum and minimum offset is 14 positive or negative hours. If - \a seconds is larger or smaller than that, the result is undefined. + switch (spec) { + case Qt::UTC: + return QDateTime(newDate, newTime, Qt::UTC); + case Qt::OffsetFromUTC: + utcToOffset(&newDate, &newTime, offsetSeconds); + return QDateTime(newDate, newTime, Qt::OffsetFromUTC, offsetSeconds); + default: + utcToLocal(newDate, newTime); + return QDateTime(newDate, newTime, Qt::LocalTime); + } +} - 0 as offset is identical to UTC. Therefore, if \a seconds is 0, the - timeSpec() will be set to Qt::UTC. Hence the UTC offset always - relates to UTC, and can never relate to local time. +#if QT_DEPRECATED_SINCE(5, 2) +/*! + \since 4.4 + \internal + \obsolete - \sa isValid(), utcOffset() + This method was added in 4.4 but never documented as public. It was replaced + in 5.2 with public method setOffsetFromUtc() for consistency with QTimeZone. + + This method should never be made public. + + \sa setOffsetFromUtc() */ void QDateTime::setUtcOffset(int seconds) { - detach(); - - /* The motivation to also setting d->spec is to ensure that the QDateTime - * instance stays in well-defined states all the time; instead of that, - * we instruct the user to ensure it. */ - if(seconds == 0) - d->spec = QDateTimePrivate::UTC; - else - d->spec = QDateTimePrivate::OffsetFromUTC; - - /* Even if seconds is 0 we assign it to utcOffset. */ - d->utcOffset = seconds; + setOffsetFromUtc(seconds); } /*! - \since 4.4 - \internal - - Returns the UTC offset in seconds. If the timeSpec() isn't - Qt::OffsetFromUTC, 0 is returned. However, since 0 is a valid UTC - offset, the return value of this function cannot be used to determine - whether a utcOffset() is used or is valid; in that case, timeSpec() must be - checked. + \since 4.4 + \internal + \obsolete - Likewise, if this QDateTime() is invalid or if timeSpec() isn't - Qt::OffsetFromUTC, 0 is returned. + This method was added in 4.4 but never documented as public. It was replaced + in 5.1 with public method offsetFromUTC() for consistency with QTimeZone. - The UTC offset only applies if the timeSpec() is Qt::OffsetFromUTC. + This method should never be made public. - \sa isValid(), setUtcOffset() - */ + \sa offsetFromUTC() +*/ int QDateTime::utcOffset() const { - if(isValid() && d->spec == QDateTimePrivate::OffsetFromUTC) - return d->utcOffset; - else - return 0; + return offsetFromUtc(); } +#endif // QT_DEPRECATED_SINCE #ifndef QT_NO_DATESTRING @@ -3370,26 +3598,15 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f) } // Recognize timezone specifications - QRegExp rx(QLatin1String("[+-]")); - if (tmp.contains(rx)) { - int idx = tmp.indexOf(rx); - QString tmp2 = tmp.mid(idx); - tmp = tmp.left(idx); - bool ok = true; - int ntzhour = 1; - int ntzminute = 3; - if ( tmp2.indexOf(QLatin1Char(':')) == 3 ) - ntzminute = 4; - const int tzhour(tmp2.mid(ntzhour, 2).toInt(&ok)); - const int tzminute(tmp2.mid(ntzminute, 2).toInt(&ok)); - QTime tzt(tzhour, tzminute); - int utcOffset = (tzt.hour() * 60 + tzt.minute()) * 60; - if ( utcOffset != 0 ) { - ts = Qt::OffsetFromUTC; - QDateTime dt(date, QTime::fromString(tmp, Qt::ISODate), ts); - dt.setUtcOffset( utcOffset * (tmp2.startsWith(QLatin1Char('-')) ? -1 : 1) ); - return dt; - } + int offset = 0; + const int signIndex = tmp.indexOf(QRegExp(QStringLiteral("[+-]"))); + if (signIndex >= 0) { + bool ok; + offset = fromOffsetString(tmp.mid(signIndex), &ok); + if (!ok) + return QDateTime(); + tmp = tmp.left(signIndex); + ts = Qt::OffsetFromUTC; } bool isMidnight24 = false; @@ -3400,7 +3617,7 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f) date = date.addDays(1); } - return QDateTime(date, time, ts); + return QDateTime(date, time, ts, offset); } case Qt::RFC2822Date: { QDate date; @@ -3412,7 +3629,7 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f) return QDateTime(); QDateTime dateTime(date, time, Qt::UTC); - dateTime.setUtcOffset(utcOffset); + dateTime.setOffsetFromUtc(utcOffset); return dateTime; } case Qt::SystemLocaleDate: @@ -3521,26 +3738,15 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f) QString tz = parts.at(5); if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive)) return QDateTime(); - QDateTime dt(date, time, Qt::UTC); - if (tz.length() > 3) { - int tzoffset = 0; - QChar sign = tz.at(3); - if ((sign != QLatin1Char('+')) - && (sign != QLatin1Char('-'))) { - return QDateTime(); - } - int tzhour = tz.mid(4, 2).toInt(&ok); - if (!ok) - return QDateTime(); - int tzminute = tz.mid(6).toInt(&ok); + tz.remove(0, 3); + if (!tz.isEmpty()) { + int offset = fromOffsetString(tz, &ok); if (!ok) return QDateTime(); - tzoffset = (tzhour*60 + tzminute) * 60; - if (sign == QLatin1Char('-')) - tzoffset = -tzoffset; - dt.setUtcOffset(tzoffset); + return QDateTime(date, time, Qt::OffsetFromUTC, offset); + } else { + return QDateTime(date, time, Qt::UTC); } - return dt.toLocalTime(); } #endif //QT_NO_TEXTDATE } @@ -3790,7 +3996,7 @@ QDataStream &operator>>(QDataStream &in, QTime &time) */ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) { - if (out.version() == 13) { + if (out.version() == QDataStream::Qt_5_0) { if (dateTime.isValid()) { // This approach is wrong and should not be used again; it breaks // the guarantee that a deserialised local datetime is the same time @@ -3803,8 +4009,12 @@ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) out << (qint8)dateTime.timeSpec(); } else { out << dateTime.d->date << dateTime.d->time; - if (out.version() >= 7) + if (out.version() >= QDataStream::Qt_4_0) out << (qint8)dateTime.d->spec; + if (out.version() >= QDataStream::Qt_5_2 + && dateTime.d->spec == QDateTimePrivate::OffsetFromUTC) { + out << qint32(dateTime.offsetFromUtc()); + } } return out; } @@ -3823,19 +4033,23 @@ QDataStream &operator>>(QDataStream &in, QDateTime &dateTime) in >> dateTime.d->date >> dateTime.d->time; - if (in.version() == 13) { + if (in.version() == QDataStream::Qt_5_0) { qint8 ts = 0; in >> ts; if (dateTime.isValid()) { - // We always store the datetime as UTC in 13 onwards. + // We incorrectly stored the datetime as UTC in Qt_5_0. dateTime.d->spec = QDateTimePrivate::UTC; dateTime = dateTime.toTimeSpec(static_cast<Qt::TimeSpec>(ts)); } } else { qint8 ts = (qint8)QDateTimePrivate::LocalUnknown; - if (in.version() >= 7) + if (in.version() >= QDataStream::Qt_4_0) in >> ts; + qint32 offset = 0; + if (in.version() >= QDataStream::Qt_5_2 && ts == qint8(QDateTimePrivate::OffsetFromUTC)) + in >> offset; dateTime.d->spec = (QDateTimePrivate::Spec)ts; + dateTime.d->m_offsetFromUtc = offset; } return in; } @@ -4129,6 +4343,7 @@ static QDate adjustDate(QDate date) return date; } +// Convert passed in UTC datetime into LocalTime and return spec static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) { QDate fakeDate = adjustDate(date); @@ -4182,6 +4397,7 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) } } +// Convert passed in LocalTime datetime into UTC static void localToUtc(QDate &date, QTime &time, int isdst) { if (!date.isValid()) @@ -4254,26 +4470,42 @@ static void localToUtc(QDate &date, QTime &time, int isdst) } } +// Convert passed in OffsetFromUTC datetime and offset into UTC +static void offsetToUtc(QDate *outDate, QTime *outTime, qint32 offset) +{ + QDateTimePrivate::addMSecs(*outDate, *outTime, -(qint64(offset) * 1000)); +} + +// Convert passed in UTC datetime and offset into OffsetFromUTC +static void utcToOffset(QDate *outDate, QTime *outTime, qint32 offset) +{ + QDateTimePrivate::addMSecs(*outDate, *outTime, (qint64(offset) * 1000)); +} + +// Get current date/time in LocalTime and put result in outDate and outTime QDateTimePrivate::Spec QDateTimePrivate::getLocal(QDate &outDate, QTime &outTime) const { outDate = date; outTime = time; if (spec == QDateTimePrivate::UTC) return utcToLocal(outDate, outTime); + if (spec == QDateTimePrivate::OffsetFromUTC) { + offsetToUtc(&outDate, &outTime, m_offsetFromUtc); + return utcToLocal(outDate, outTime); + } return spec; } +// Get current date/time in UTC and put result in outDate and outTime void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const { outDate = date; outTime = time; - const bool isOffset = spec == QDateTimePrivate::OffsetFromUTC; - if (spec != QDateTimePrivate::UTC && !isOffset) + if (spec == QDateTimePrivate::OffsetFromUTC) + offsetToUtc(&outDate, &outTime, m_offsetFromUtc); + else if (spec != QDateTimePrivate::UTC) localToUtc(outDate, outTime, (int)spec); - - if (isOffset) - addMSecs(outDate, outTime, -(qint64(utcOffset) * 1000)); } #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING) diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index e5c1e104a2..3c8b1a9920 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -203,6 +203,8 @@ public: QDateTime(); explicit QDateTime(const QDate &); QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime); + // ### Qt 6: Merge with above with default offsetSeconds = 0 + QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds); QDateTime(const QDateTime &other); ~QDateTime(); @@ -216,15 +218,20 @@ public: QDate date() const; QTime time() const; Qt::TimeSpec timeSpec() const; + int offsetFromUtc() const; + qint64 toMSecsSinceEpoch() const; // ### Qt 6: use quint64 instead of uint uint toTime_t() const; + void setDate(const QDate &date); void setTime(const QTime &time); void setTimeSpec(Qt::TimeSpec spec); + void setOffsetFromUtc(int offsetSeconds); void setMSecsSinceEpoch(qint64 msecs); // ### Qt 6: use quint64 instead of uint void setTime_t(uint secsSince1Jan1970UTC); + #ifndef QT_NO_DATESTRING QString toString(Qt::DateFormat f = Qt::TextDate) const; QString toString(const QString &format) const; @@ -234,9 +241,12 @@ public: QDateTime addYears(int years) const; QDateTime addSecs(qint64 secs) const; QDateTime addMSecs(qint64 msecs) const; + QDateTime toTimeSpec(Qt::TimeSpec spec) const; inline QDateTime toLocalTime() const { return toTimeSpec(Qt::LocalTime); } inline QDateTime toUTC() const { return toTimeSpec(Qt::UTC); } + QDateTime toOffsetFromUtc(int offsetSeconds) const; + qint64 daysTo(const QDateTime &) const; qint64 secsTo(const QDateTime &) const; qint64 msecsTo(const QDateTime &) const; @@ -248,8 +258,10 @@ public: inline bool operator>(const QDateTime &other) const { return other < *this; } inline bool operator>=(const QDateTime &other) const { return !(*this < other); } - void setUtcOffset(int seconds); - int utcOffset() const; +#if QT_DEPRECATED_SINCE(5, 2) + QT_DEPRECATED void setUtcOffset(int seconds); + QT_DEPRECATED int utcOffset() const; +#endif // QT_DEPRECATED_SINCE static QDateTime currentDateTime(); static QDateTime currentDateTimeUtc(); @@ -259,7 +271,12 @@ public: #endif // ### Qt 6: use quint64 instead of uint static QDateTime fromTime_t(uint secsSince1Jan1970UTC); + // ### Qt 6: Merge with above with default spec = Qt::LocalTime + static QDateTime fromTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec, + int offsetFromUtc = 0); static QDateTime fromMSecsSinceEpoch(qint64 msecs); + // ### Qt 6: Merge with above with default spec = Qt::LocalTime + static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetFromUtc = 0); static qint64 currentMSecsSinceEpoch() Q_DECL_NOTHROW; private: diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h index c70571d509..f3abcf02d8 100644 --- a/src/corelib/tools/qdatetime_p.h +++ b/src/corelib/tools/qdatetime_p.h @@ -81,25 +81,27 @@ class QDateTimePrivate : public QSharedData public: enum Spec { LocalUnknown = -1, LocalStandard = 0, LocalDST = 1, UTC = 2, OffsetFromUTC = 3}; - QDateTimePrivate() : spec(LocalUnknown), utcOffset(0) {} + QDateTimePrivate() : spec(LocalUnknown), m_offsetFromUtc(0) {} + QDateTimePrivate(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec, + int offsetSeconds); QDateTimePrivate(const QDateTimePrivate &other) - : QSharedData(other), date(other.date), time(other.time), spec(other.spec), utcOffset(other.utcOffset) + : QSharedData(other), date(other.date), time(other.time), spec(other.spec), + m_offsetFromUtc(other.m_offsetFromUtc) {} QDate date; QTime time; Spec spec; - /*! - \internal - \since 4.4 - - The offset in seconds. Applies only when timeSpec() is OffsetFromUTC. - */ - int utcOffset; + int m_offsetFromUtc; + // Get current date/time in LocalTime and put result in outDate and outTime Spec getLocal(QDate &outDate, QTime &outTime) const; + // Get current date/time in UTC and put result in outDate and outTime void getUTC(QDate &outDate, QTime &outTime) const; + + // Add msecs to given datetime and return result static QDateTime addMSecs(const QDateTime &dt, qint64 msecs); + // Add msecs to given datetime and put result in utcDate and utcTime static void addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs); static inline qint64 minJd() { return QDate::minJd(); } diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 3cd967c84b..9dd0e6144d 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -845,14 +845,14 @@ Q_OUTOFLINE_TEMPLATE T QHash<Key, T>::take(const Key &akey) template <class Key, class T> Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::erase(iterator it) { - Q_ASSERT_X(isValidIterator(it), "QHash::erase", "The specified const_iterator argument 'it' is invalid"); + Q_ASSERT_X(isValidIterator(it), "QHash::erase", "The specified iterator argument 'it' is invalid"); if (it == iterator(e)) return it; if (d->ref.isShared()) { int bucketNum = (it.i->h % d->numBuckets); - const_iterator bucketIterator(*(d->buckets + bucketNum)); + iterator bucketIterator(*(d->buckets + bucketNum)); int stepsFromBucketStartToIte = 0; while (bucketIterator != it) { ++stepsFromBucketStartToIte; diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp index e695ac0f4d..072a35aa4e 100644 --- a/src/corelib/tools/qlocale_tools.cpp +++ b/src/corelib/tools/qlocale_tools.cpp @@ -1064,15 +1064,7 @@ static Bigint *pow5mult(Bigint *b, int k) static const int p05[3] = { 5, 25, 125 }; if ((i = k & 3) != 0) -#if defined(Q_OS_IRIX) && defined(Q_CC_GNU) - { - // work around a bug on 64 bit IRIX gcc - int *p = (int *) p05; - b = multadd(b, p[i-1], 0); - } -#else b = multadd(b, p05[i-1], 0); -#endif if (!(k >>= 2)) return b; @@ -1666,15 +1658,7 @@ Q_CORE_EXPORT double qstrtod(const char *s00, const char **se, bool *ok) k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; rv = y; if (k > 9) -#if defined(Q_OS_IRIX) && defined(Q_CC_GNU) - { - // work around a bug on 64 bit IRIX gcc - double *t = (double *) tens; - rv = t[k - 9] * rv + z; - } -#else rv = tens[k - 9] * rv + z; -#endif bd0 = 0; if (nd <= DBL_DIG @@ -2570,13 +2554,7 @@ static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, else { #endif /* Generate ilim digits, then fix them up. */ -#if defined(Q_OS_IRIX) && defined(Q_CC_GNU) - // work around a bug on 64 bit IRIX gcc - double *t = (double *) tens; - eps *= t[ilim-1]; -#else eps *= tens[ilim-1]; -#endif for(i = 1;; i++, d *= 10.) { L = Long(d); d -= L; diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 047fcbfc30..22155d6d3a 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.cpp @@ -133,7 +133,6 @@ QT_BEGIN_NAMESPACE Constructs this QScopedPointer instance and sets its pointer to \a p. */ -#ifndef Q_QDOC // QTBUG-32675, qdoc can't parse rvalue refs /*! \fn QScopedPointer::QScopedPointer(QScopedPointer<T, Cleanup> &&other) @@ -154,11 +153,10 @@ QT_BEGIN_NAMESPACE Otherwise, this instance is set to point to the object \a other is pointing to, and \a other is set to point to \c{NULL}. - If this instance was pointing to an object, that object is destroyed, + If this instance was pointing to an object, that object is destroyed. \since 5.2 */ -#endif /*! \fn QScopedPointer::~QScopedPointer() diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 49f9fc0cd8..e990e7d18b 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -221,7 +221,7 @@ void QDBusPendingCallPrivate::checkReceivedSignature() return; // no signature to validate against // can't use startsWith here because a null string doesn't start or end with an empty string - if (!replyMessage.signature().indexOf(expectedReplySignature) == 0) { + if (replyMessage.signature().indexOf(expectedReplySignature) != 0) { QString errorMsg = QLatin1String("Unexpected reply signature: got \"%1\", " "expected \"%2\""); replyMessage = QDBusMessage::createError( diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp index d9e9c4b17c..404700292c 100644 --- a/src/gui/kernel/qplatformdialoghelper.cpp +++ b/src/gui/kernel/qplatformdialoghelper.cpp @@ -359,6 +359,7 @@ public: QDir::Filters filters; QList<QUrl> sidebarUrls; QStringList nameFilters; + QStringList mimeTypeFilters; QString defaultSuffix; QStringList history; QUrl initialDirectory; @@ -477,6 +478,16 @@ QStringList QFileDialogOptions::nameFilters() const return d->nameFilters; } +void QFileDialogOptions::setMimeTypeFilters(const QStringList &filters) +{ + d->mimeTypeFilters = filters; +} + +QStringList QFileDialogOptions::mimeTypeFilters() const +{ + return d->mimeTypeFilters; +} + void QFileDialogOptions::setDefaultSuffix(const QString &suffix) { d->defaultSuffix = suffix; diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h index 6d7d52ccb1..5269416ffd 100644 --- a/src/gui/kernel/qplatformdialoghelper.h +++ b/src/gui/kernel/qplatformdialoghelper.h @@ -265,6 +265,9 @@ public: void setNameFilters(const QStringList &filters); QStringList nameFilters() const; + void setMimeTypeFilters(const QStringList &filters); + QStringList mimeTypeFilters() const; + void setDefaultSuffix(const QString &suffix); QString defaultSuffix() const; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index cfb9d71f5c..f65a46f0db 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -780,8 +780,8 @@ void QPainterPrivate::updateEmulationSpecifier(QPainterState *s) complexXform = !s->matrix.isAffine(); } - const bool brushXform = (!s->brush.transform().type() == QTransform::TxNone); - const bool penXform = (!s->pen.brush().transform().type() == QTransform::TxNone); + const bool brushXform = (s->brush.transform().type() != QTransform::TxNone); + const bool penXform = (s->pen.brush().transform().type() != QTransform::TxNone); const bool patternXform = patternBrush && (xform || brushXform || penXform); diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index e2e99893c8..084ef6cea3 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -75,11 +75,12 @@ class QFontEngineFTRawFont; class QFontconfigDatabase; /* - * This struct represents one font file on disk (like Arial.ttf) and is shared between all the font engines + * This class represents one font file on disk (like Arial.ttf) and is shared between all the font engines * that show this font file (at different pixel sizes). */ -struct QFreetypeFace +class QFreetypeFace { +public: void computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing); QFontEngine::Properties properties() const; bool getSfntTable(uint tag, uchar *buffer, uint *length) const; diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index 173f825b23..a77e1a643c 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -1042,18 +1042,10 @@ bool QFtpPI::processReply() if (static_cast<signed char>(replyCode[0]) < 0 || replyCode[0] > 5) state = Failure; else -#if defined(Q_OS_IRIX) && defined(Q_CC_GNU) - { - // work around a crash on 64 bit gcc IRIX - State *t = (State *) table; - state = t[replyCode[0] - 1]; - } -#else if (replyCodeInt == 202) state = Failure; else state = table[replyCode[0] - 1]; -#endif break; default: // ignore unrequested message diff --git a/src/plugins/platforminputcontexts/maliit/contextadaptor.cpp b/src/plugins/platforminputcontexts/maliit/contextadaptor.cpp deleted file mode 100644 index 134ff94f6b..0000000000 --- a/src/plugins/platforminputcontexts/maliit/contextadaptor.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "contextadaptor.h" -#include <QtCore/QByteArray> -#include <QtCore/QList> -#include <QtCore/QMetaObject> -#include <QtCore/QMap> -#include <QtCore/QString> -#include <QtCore/QStringList> -#include <QtCore/QVariant> - -#include "qmaliitplatforminputcontext.h" - -/* - * Implementation of adaptor class Inputcontext1Adaptor - */ - -Inputcontext1Adaptor::Inputcontext1Adaptor(QObject *parent) - : QDBusAbstractAdaptor(parent) -{ - // constructor - setAutoRelaySignals(true); -} - -Inputcontext1Adaptor::~Inputcontext1Adaptor() -{ - // destructor -} - -void Inputcontext1Adaptor::activationLostEvent() -{ - // handle method call com.meego.inputmethod.inputcontext1.activationLostEvent - QMetaObject::invokeMethod(parent(), "activationLostEvent"); -} - -void Inputcontext1Adaptor::commitString(const QString &in0, int in1, int in2, int in3) -{ - // handle method call com.meego.inputmethod.inputcontext1.commitString - QMetaObject::invokeMethod(parent(), "commitString", Q_ARG(QString, in0), Q_ARG(int, in1), Q_ARG(int, in2), Q_ARG(int, in3)); -} - -void Inputcontext1Adaptor::updatePreedit(const QDBusMessage &message) -{ - // handle method call com.meego.inputmethod.inputcontext1.updatePreedit - QMetaObject::invokeMethod(parent(), "updatePreedit", Q_ARG(QDBusMessage, message)); -} - -void Inputcontext1Adaptor::copy() -{ - // handle method call com.meego.inputmethod.inputcontext1.copy - QMetaObject::invokeMethod(parent(), "copy"); -} - -void Inputcontext1Adaptor::imInitiatedHide() -{ - // handle method call com.meego.inputmethod.inputcontext1.imInitiatedHide - QMetaObject::invokeMethod(parent(), "imInitiatedHide"); -} - -void Inputcontext1Adaptor::keyEvent(int in0, int in1, int in2, const QString &in3, bool in4, int in5, uchar in6) -{ - // handle method call com.meego.inputmethod.inputcontext1.keyEvent - QMetaObject::invokeMethod(parent(), "keyEvent", Q_ARG(int, in0), Q_ARG(int, in1), Q_ARG(int, in2), Q_ARG(QString, in3), Q_ARG(bool, in4), Q_ARG(int, in5), Q_ARG(uchar, in6)); -} - -void Inputcontext1Adaptor::paste() -{ - // handle method call com.meego.inputmethod.inputcontext1.paste - QMetaObject::invokeMethod(parent(), "paste"); -} - -bool Inputcontext1Adaptor::preeditRectangle(int &out1, int &out2, int &out3, int &out4) -{ - // handle method call com.meego.inputmethod.inputcontext1.preeditRectangle - return static_cast<QMaliitPlatformInputContext *>(parent())->preeditRectangle(out1, out2, out3, out4); -} - -bool Inputcontext1Adaptor::selection(QString &out1) -{ - // handle method call com.meego.inputmethod.inputcontext1.selection - return static_cast<QMaliitPlatformInputContext *>(parent())->selection(out1); -} - -void Inputcontext1Adaptor::setDetectableAutoRepeat(bool in0) -{ - // handle method call com.meego.inputmethod.inputcontext1.setDetectableAutoRepeat - QMetaObject::invokeMethod(parent(), "setDetectableAutoRepeat", Q_ARG(bool, in0)); -} - -void Inputcontext1Adaptor::setGlobalCorrectionEnabled(bool in0) -{ - // handle method call com.meego.inputmethod.inputcontext1.setGlobalCorrectionEnabled - QMetaObject::invokeMethod(parent(), "setGlobalCorrectionEnabled", Q_ARG(bool, in0)); -} - -void Inputcontext1Adaptor::setLanguage(const QString &in0) -{ - // handle method call com.meego.inputmethod.inputcontext1.setLanguage - QMetaObject::invokeMethod(parent(), "setLanguage", Q_ARG(QString, in0)); -} - -void Inputcontext1Adaptor::setRedirectKeys(bool in0) -{ - // handle method call com.meego.inputmethod.inputcontext1.setRedirectKeys - QMetaObject::invokeMethod(parent(), "setRedirectKeys", Q_ARG(bool, in0)); -} - -void Inputcontext1Adaptor::setSelection(int in0, int in1) -{ - // handle method call com.meego.inputmethod.inputcontext1.setSelection - QMetaObject::invokeMethod(parent(), "setSelection", Q_ARG(int, in0), Q_ARG(int, in1)); -} - -void Inputcontext1Adaptor::updateInputMethodArea(int in0, int in1, int in2, int in3) -{ - // handle method call com.meego.inputmethod.inputcontext1.updateInputMethodArea - QMetaObject::invokeMethod(parent(), "updateInputMethodArea", Q_ARG(int, in0), Q_ARG(int, in1), Q_ARG(int, in2), Q_ARG(int, in3)); -} - diff --git a/src/plugins/platforminputcontexts/maliit/contextadaptor.h b/src/plugins/platforminputcontexts/maliit/contextadaptor.h deleted file mode 100644 index e959a7cb5b..0000000000 --- a/src/plugins/platforminputcontexts/maliit/contextadaptor.h +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CONTEXT_H_1318935171 -#define CONTEXT_H_1318935171 - -#include <QtCore/QObject> -#include <QtCore/QByteArray> -#include <QtCore/QList> -#include <QtCore/QMap> -#include <QtCore/QString> -#include <QtCore/QStringList> -#include <QtCore/QVariant> -#include <QtDBus/QtDBus> - -/* - * Adaptor class for interface com.meego.inputmethod.inputcontext1 - */ -class Inputcontext1Adaptor: public QDBusAbstractAdaptor -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "com.meego.inputmethod.inputcontext1") - Q_CLASSINFO("D-Bus Introspection", "" -" <interface name=\"com.meego.inputmethod.inputcontext1\">\n" -" <method name=\"activationLostEvent\"/>\n" -" <method name=\"imInitiatedHide\"/>\n" -" <method name=\"commitString\">\n" -" <arg type=\"s\"/>\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" </method>\n" -" <method name=\"updatePreedit\">\n" -" <arg type=\"s\"/>\n" -" <arg type=\"a(iii)\"/>\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" </method>\n" -" <method name=\"keyEvent\">\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" <arg type=\"s\"/>\n" -" <arg type=\"b\"/>\n" -" <arg type=\"i\"/>\n" -" <arg type=\"y\"/>\n" -" </method>\n" -" <method name=\"updateInputMethodArea\">\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" </method>\n" -" <method name=\"setGlobalCorrectionEnabled\">\n" -" <arg type=\"b\"/>\n" -" </method>\n" -" <method name=\"preeditRectangle\">\n" -" <arg direction=\"out\" type=\"b\"/>\n" -" <arg direction=\"out\" type=\"i\"/>\n" -" <arg direction=\"out\" type=\"i\"/>\n" -" <arg direction=\"out\" type=\"i\"/>\n" -" <arg direction=\"out\" type=\"i\"/>\n" -" </method>\n" -" <method name=\"copy\"/>\n" -" <method name=\"paste\"/>\n" -" <method name=\"setRedirectKeys\">\n" -" <arg type=\"b\"/>\n" -" </method>\n" -" <method name=\"setDetectableAutoRepeat\">\n" -" <arg type=\"b\"/>\n" -" </method>\n" -" <method name=\"setSelection\">\n" -" <arg type=\"i\"/>\n" -" <arg type=\"i\"/>\n" -" </method>\n" -" <method name=\"selection\">\n" -" <arg direction=\"out\" type=\"b\"/>\n" -" <arg direction=\"out\" type=\"s\"/>\n" -" </method>\n" -" <method name=\"setLanguage\">\n" -" <arg type=\"s\"/>\n" -" </method>\n" -" </interface>\n" - "") -public: - Inputcontext1Adaptor(QObject *parent); - virtual ~Inputcontext1Adaptor(); - -public: // PROPERTIES -public Q_SLOTS: // METHODS - void activationLostEvent(); - void commitString(const QString &in0, int in1, int in2, int in3); - void updatePreedit(const QDBusMessage &message); - void copy(); - void imInitiatedHide(); - void keyEvent(int in0, int in1, int in2, const QString &in3, bool in4, int in5, uchar in6); - void paste(); - bool preeditRectangle(int &out1, int &out2, int &out3, int &out4); - bool selection(QString &out1); - void setDetectableAutoRepeat(bool in0); - void setGlobalCorrectionEnabled(bool in0); - void setLanguage(const QString &in0); - void setRedirectKeys(bool in0); - void setSelection(int in0, int in1); - void updateInputMethodArea(int in0, int in1, int in2, int in3); -Q_SIGNALS: // SIGNALS -}; - -#endif diff --git a/src/plugins/platforminputcontexts/maliit/main.cpp b/src/plugins/platforminputcontexts/maliit/main.cpp deleted file mode 100644 index ca4845afd7..0000000000 --- a/src/plugins/platforminputcontexts/maliit/main.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qpa/qplatforminputcontextplugin_p.h> -#include <QtCore/QStringList> -#include "qmaliitplatforminputcontext.h" - -QT_BEGIN_NAMESPACE - -class QMaliitPlatformInputContextPlugin : public QPlatformInputContextPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface" FILE "maliit.json") - -public: - QPlatformInputContext *create(const QString&, const QStringList&); -}; - -QPlatformInputContext *QMaliitPlatformInputContextPlugin::create(const QString& system, const QStringList& paramList) -{ - Q_UNUSED(paramList); - - if (system.compare(system, QStringLiteral("maliit"), Qt::CaseInsensitive) == 0) - return new QMaliitPlatformInputContext; - return 0; -} - -QT_END_NAMESPACE - -#include "main.moc" diff --git a/src/plugins/platforminputcontexts/maliit/maliit.json b/src/plugins/platforminputcontexts/maliit/maliit.json deleted file mode 100644 index f828e1426e..0000000000 --- a/src/plugins/platforminputcontexts/maliit/maliit.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": [ "maliit" ] -} diff --git a/src/plugins/platforminputcontexts/maliit/maliit.pro b/src/plugins/platforminputcontexts/maliit/maliit.pro deleted file mode 100644 index 1e50f7289b..0000000000 --- a/src/plugins/platforminputcontexts/maliit/maliit.pro +++ /dev/null @@ -1,19 +0,0 @@ -TARGET = maliitplatforminputcontextplugin - -PLUGIN_TYPE = platforminputcontexts -PLUGIN_CLASS_NAME = QMaliitPlatformInputContextPlugin -load(qt_plugin) - -QT += dbus gui-private -SOURCES += $$PWD/qmaliitplatforminputcontext.cpp \ - $$PWD/serverproxy.cpp \ - $$PWD/serveraddressproxy.cpp \ - $$PWD/contextadaptor.cpp \ - $$PWD/main.cpp - -HEADERS += $$PWD/qmaliitplatforminputcontext.h \ - $$PWD/serverproxy.h \ - $$PWD/serveraddressproxy.h \ - $$PWD/contextadaptor.h - -OTHER_FILES += $$PWD/maliit.json diff --git a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp b/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp deleted file mode 100644 index 6d748d44a1..0000000000 --- a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.cpp +++ /dev/null @@ -1,583 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "qmaliitplatforminputcontext.h" - -#include <QtDebug> -#include <QTextCharFormat> -#include <QGuiApplication> -#include <qwindow.h> -#include <qevent.h> -#include <qscreen.h> - -#include "serveraddressproxy.h" -#include "serverproxy.h" -#include "contextadaptor.h" - -#include <sys/types.h> -#include <signal.h> - -#include <QtDBus> - -QT_BEGIN_NAMESPACE - -enum { debug = 0 }; - -enum InputPanelVisibility { - InputPanelHidden, - InputPanelShowRequested, - InputPanelShown -}; - -enum MaliitOrientationAngle { - Angle0 = 0, - Angle90 = 90, - Angle180 = 180, - Angle270 = 270 -}; - -static int orientationAngle(Qt::ScreenOrientation orientation) -{ - switch (orientation) { - case Qt::PrimaryOrientation: // Urgh. - case Qt::PortraitOrientation: - return Angle270; - case Qt::LandscapeOrientation: - return Angle0; - case Qt::InvertedPortraitOrientation: - return Angle90; - case Qt::InvertedLandscapeOrientation: - return Angle180; - } - return Angle0; -} - -// From MTF: -//! Content type for text entries. Used at least with MTextEdit -enum TextContentType { - //! all characters allowed - FreeTextContentType, - - //! only integer numbers allowed - NumberContentType, - - //! allows numbers and certain other characters used in phone numbers - PhoneNumberContentType, - - //! allows only characters permitted in email address - EmailContentType, - - //! allows only character permitted in URL address - UrlContentType, - - //! allows content with user defined format - CustomContentType -}; -static TextContentType contentTypeFromHints(Qt::InputMethodHints hints) -{ - TextContentType type = FreeTextContentType; - hints &= Qt::ImhExclusiveInputMask; - - if (hints == Qt::ImhFormattedNumbersOnly || hints == Qt::ImhDigitsOnly) - type = NumberContentType; - else if (hints == Qt::ImhDialableCharactersOnly) - type = PhoneNumberContentType; - else if (hints == Qt::ImhEmailCharactersOnly) - type = EmailContentType; - else if (hints == Qt::ImhUrlCharactersOnly) - type = UrlContentType; - - return type; -} - -/// From Maliit's namespace.h -enum MaliitEventRequestType { - EventRequestBoth, //!< Both a Qt::KeyEvent and a signal - EventRequestSignalOnly, //!< Only a signal - EventRequestEventOnly //!< Only a Qt::KeyEvent -}; - -static QString maliitServerAddress() -{ - org::maliit::Server::Address serverAddress(QStringLiteral("org.maliit.server"), QStringLiteral("/org/maliit/server/address"), QDBusConnection::sessionBus()); - - QString address(serverAddress.address()); - - // Fallback to old socket when org.maliit.server service is not available - if (address.isEmpty()) - return QStringLiteral("unix:path=/tmp/meego-im-uiserver/imserver_dbus"); - - return address; -} - -class QMaliitPlatformInputContextPrivate -{ -public: - QMaliitPlatformInputContextPrivate(QMaliitPlatformInputContext *qq); - ~QMaliitPlatformInputContextPrivate() - { - delete adaptor; - delete server; - } - - void sendStateUpdate(bool focusChanged = false); - - QDBusConnection connection; - ComMeegoInputmethodUiserver1Interface *server; - Inputcontext1Adaptor *adaptor; - - QMap<QString, QVariant> imState; - - InputPanelVisibility visibility; - - bool valid; - bool active; - bool correctionEnabled; - QRect keyboardRect; - QString preedit; - QPointer<QWindow> window; - QMaliitPlatformInputContext *q; -}; - - -QMaliitPlatformInputContext::QMaliitPlatformInputContext() - : d(new QMaliitPlatformInputContextPrivate(this)) -{ - if (debug) - qDebug() << "QMaliitPlatformInputContext::QMaliitPlatformInputContext()"; -} - -QMaliitPlatformInputContext::~QMaliitPlatformInputContext(void) -{ - delete d; -} - -bool QMaliitPlatformInputContext::isValid() const -{ - return d->valid; -} - -void QMaliitPlatformInputContext::invokeAction(QInputMethod::Action action, int x) -{ - if (!inputMethodAccepted()) - return; - - if (action == QInputMethod::Click) { - if (x < 0 || x >= d->preedit.length()) { - reset(); - return; - } - - d->imState["preeditClickPos"] = x; - d->sendStateUpdate(); - // The first argument is the mouse pos and the second is the - // preedit rectangle. Both are unused on the server side. - d->server->mouseClickedOnPreedit(0, 0, 0, 0, 0, 0); - } else { - QPlatformInputContext::invokeAction(action, x); - } -} - -void QMaliitPlatformInputContext::reset() -{ - const bool hadPreedit = !d->preedit.isEmpty(); - if (hadPreedit && inputMethodAccepted()) { - // ### selection - QInputMethodEvent event; - event.setCommitString(d->preedit); - QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); - d->preedit.clear(); - } - - QDBusPendingReply<void> reply = d->server->reset(); - if (hadPreedit) - reply.waitForFinished(); -} - -void QMaliitPlatformInputContext::update(Qt::InputMethodQueries queries) -{ - if (!qGuiApp->focusObject()) - return; - - QInputMethodQueryEvent query(queries); - QGuiApplication::sendEvent(qGuiApp->focusObject(), &query); - - if (queries & Qt::ImSurroundingText) - d->imState["surroundingText"] = query.value(Qt::ImSurroundingText); - if (queries & Qt::ImCursorPosition) - d->imState["cursorPosition"] = query.value(Qt::ImCursorPosition); - if (queries & Qt::ImAnchorPosition) - d->imState["anchorPosition"] = query.value(Qt::ImAnchorPosition); - if (queries & Qt::ImCursorRectangle) { - QRect rect = query.value(Qt::ImCursorRectangle).toRect(); - rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(rect); - QWindow *window = qGuiApp->focusWindow(); - if (window) - d->imState["cursorRectangle"] = QRect(window->mapToGlobal(rect.topLeft()), rect.size()); - } - - if (queries & Qt::ImCurrentSelection) - d->imState["hasSelection"] = !query.value(Qt::ImCurrentSelection).toString().isEmpty(); - - if (queries & Qt::ImHints) { - Qt::InputMethodHints hints = Qt::InputMethodHints(query.value(Qt::ImHints).toUInt()); - - d->imState["predictionEnabled"] = !(hints & Qt::ImhNoPredictiveText); - d->imState["autocapitalizationEnabled"] = !(hints & Qt::ImhNoAutoUppercase); - d->imState["hiddenText"] = (hints & Qt::ImhHiddenText) != 0; - - d->imState["contentType"] = contentTypeFromHints(hints); - } - - d->sendStateUpdate(/*focusChanged*/true); -} - -QRectF QMaliitPlatformInputContext::keyboardRect() const -{ - return d->keyboardRect; -} - -void QMaliitPlatformInputContext::activationLostEvent() -{ - d->active = false; - d->visibility = InputPanelHidden; -} - -void QMaliitPlatformInputContext::commitString(const QString &string, int replacementStart, int replacementLength, int /* cursorPos */) -{ - if (!inputMethodAccepted()) - return; - - d->preedit.clear(); - - if (debug) - qWarning() << "CommitString" << string; - // ### start/cursorPos - QInputMethodEvent event; - event.setCommitString(string, replacementStart, replacementLength); - QCoreApplication::sendEvent(qGuiApp->focusObject(), &event); -} - -void QMaliitPlatformInputContext::updatePreedit(const QDBusMessage &message) -{ - if (!inputMethodAccepted()) - return; - - QList<QVariant> arguments = message.arguments(); - if (arguments.count() != 5) { - qWarning() << "QMaliitPlatformInputContext::updatePreedit: Received message from input method server with wrong parameters."; - return; - } - - d->preedit = arguments[0].toString(); - - QList<QInputMethodEvent::Attribute> attributes; - - const QDBusArgument formats = arguments[1].value<QDBusArgument>(); - formats.beginArray(); - while (!formats.atEnd()) { - formats.beginStructure(); - int start, length, preeditFace; - formats >> start >> length >> preeditFace; - formats.endStructure(); - - QTextCharFormat format; - - enum PreeditFace { - PreeditDefault, - PreeditNoCandidates, - PreeditKeyPress, //!< Used for displaying the hwkbd key just pressed - PreeditUnconvertible, //!< Inactive preedit region, not clickable - PreeditActive, //!< Preedit region with active suggestions - - }; - switch (PreeditFace(preeditFace)) { - case PreeditDefault: - case PreeditKeyPress: - format.setUnderlineStyle(QTextCharFormat::SingleUnderline); - format.setUnderlineColor(QColor(0, 0, 0)); - break; - case PreeditNoCandidates: - format.setUnderlineStyle(QTextCharFormat::SingleUnderline); - format.setUnderlineColor(QColor(255, 0, 0)); - break; - case PreeditUnconvertible: - format.setForeground(QBrush(QColor(128, 128, 128))); - break; - case PreeditActive: - format.setForeground(QBrush(QColor(153, 50, 204))); - format.setFontWeight(QFont::Bold); - break; - default: - break; - } - - attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, start, length, format); - } - formats.endArray(); - - int replacementStart = arguments[2].toInt(); - int replacementLength = arguments[3].toInt(); - int cursorPos = arguments[4].toInt(); - - if (debug) - qWarning() << "updatePreedit" << d->preedit << replacementStart << replacementLength << cursorPos; - - if (cursorPos >= 0) - attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, 1, QVariant()); - - QInputMethodEvent event(d->preedit, attributes); - if (replacementStart || replacementLength) - event.setCommitString(QString(), replacementStart, replacementLength); - QCoreApplication::sendEvent(qGuiApp->focusObject(), &event); -} - -void QMaliitPlatformInputContext::copy() -{ - // Not supported at the moment. -} - -void QMaliitPlatformInputContext::imInitiatedHide() -{ - d->visibility = InputPanelHidden; - emitInputPanelVisibleChanged(); - // ### clear focus -} - -void QMaliitPlatformInputContext::keyEvent(int type, int key, int modifiers, const QString &text, - bool autoRepeat, int count, uchar requestType_) -{ - MaliitEventRequestType requestType = MaliitEventRequestType(requestType_); - if (requestType == EventRequestSignalOnly) { - qWarning() << "Maliit: Signal emitted key events are not supported."; - return; - } - - // HACK: This code relies on QEvent::Type for key events and modifiers to be binary compatible between - // Qt 4 and 5. - QEvent::Type eventType = static_cast<QEvent::Type>(type); - if (type != QEvent::KeyPress && type != QEvent::KeyRelease) { - qWarning() << "Maliit: Unknown key event type" << type; - return; - } - - QKeyEvent event(eventType, key, static_cast<Qt::KeyboardModifiers>(modifiers), - text, autoRepeat, count); - if (d->window) - QCoreApplication::sendEvent(d->window.data(), &event); -} - -void QMaliitPlatformInputContext::paste() -{ - // Not supported at the moment. -} - -bool QMaliitPlatformInputContext::preeditRectangle(int &x, int &y, int &width, int &height) -{ - // ### - QRect r = qApp->inputMethod()->cursorRectangle().toRect(); - if (!r.isValid()) - return false; - x = r.x(); - y = r.y(); - width = r.width(); - height = r.height(); - return true; -} - -bool QMaliitPlatformInputContext::selection(QString &selection) -{ - selection.clear(); - - if (!inputMethodAccepted()) - return false; - - QInputMethodQueryEvent query(Qt::ImCurrentSelection); - QGuiApplication::sendEvent(qGuiApp->focusObject(), &query); - QVariant value = query.value(Qt::ImCurrentSelection); - if (!value.isValid()) - return false; - - selection = value.toString(); - return true; -} - -void QMaliitPlatformInputContext::setDetectableAutoRepeat(bool) -{ - // Not supported. -} - -void QMaliitPlatformInputContext::setGlobalCorrectionEnabled(bool enable) -{ - d->correctionEnabled = enable; -} - -void QMaliitPlatformInputContext::setLanguage(const QString &) -{ - // Unused at the moment. -} - -void QMaliitPlatformInputContext::setRedirectKeys(bool) -{ - // Not supported. -} - -void QMaliitPlatformInputContext::setSelection(int start, int length) -{ - if (!inputMethodAccepted()) - return; - - QList<QInputMethodEvent::Attribute> attributes; - attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, start, length, QVariant()); - QInputMethodEvent event(QString(), attributes); - QGuiApplication::sendEvent(qGuiApp->focusObject(), &event); -} - -void QMaliitPlatformInputContext::updateInputMethodArea(int x, int y, int width, int height) -{ - d->keyboardRect = QRect(x, y, width, height); - emitKeyboardRectChanged(); -} - -void QMaliitPlatformInputContext::updateServerWindowOrientation(Qt::ScreenOrientation orientation) -{ - d->server->appOrientationChanged(orientationAngle(orientation)); -} - -void QMaliitPlatformInputContext::setFocusObject(QObject *object) -{ - if (!d->valid) - return; - - QWindow *window = qGuiApp->focusWindow(); - if (window != d->window.data()) { - if (d->window) - disconnect(d->window.data(), SIGNAL(contentOrientationChanged(Qt::ScreenOrientation)), - this, SLOT(updateServerWindowOrientation(Qt::ScreenOrientation))); - d->window = window; - if (d->window) - connect(d->window.data(), SIGNAL(contentOrientationChanged(Qt::ScreenOrientation)), - this, SLOT(updateServerWindowOrientation(Qt::ScreenOrientation))); - } - - d->imState["focusState"] = (object != 0); - if (inputMethodAccepted()) { - if (window) - d->imState["winId"] = static_cast<qulonglong>(window->winId()); - - if (!d->active) { - d->active = true; - d->server->activateContext(); - - if (window) - d->server->appOrientationChanged(orientationAngle(window->contentOrientation())); - } - } - d->sendStateUpdate(/*focusChanged*/true); - if (inputMethodAccepted() && window && d->visibility == InputPanelShowRequested) - showInputPanel(); -} - -void QMaliitPlatformInputContext::showInputPanel() -{ - if (debug) - qDebug() << "showInputPanel"; - - if (!inputMethodAccepted()) - d->visibility = InputPanelShowRequested; - else { - d->server->showInputMethod(); - d->visibility = InputPanelShown; - emitInputPanelVisibleChanged(); - } -} - -void QMaliitPlatformInputContext::hideInputPanel() -{ - d->server->hideInputMethod(); - d->visibility = InputPanelHidden; - emitInputPanelVisibleChanged(); -} - -bool QMaliitPlatformInputContext::isInputPanelVisible() const -{ - return d->visibility == InputPanelShown; -} - -QMaliitPlatformInputContextPrivate::QMaliitPlatformInputContextPrivate(QMaliitPlatformInputContext* qq) - : connection(QDBusConnection::connectToPeer(maliitServerAddress(), QLatin1String("MaliitIMProxy"))) - , server(0) - , adaptor(0) - , visibility(InputPanelHidden) - , valid(false) - , active(false) - , correctionEnabled(false) - , q(qq) -{ - if (!connection.isConnected()) - return; - - server = new ComMeegoInputmethodUiserver1Interface(QStringLiteral(""), QStringLiteral("/com/meego/inputmethod/uiserver1"), connection); - adaptor = new Inputcontext1Adaptor(qq); - connection.registerObject("/com/meego/inputmethod/inputcontext", qq); - - enum InputMethodMode { - //! Normal mode allows to use preedit and error correction - InputMethodModeNormal, - - //! Virtual keyboard sends QKeyEvent for every key press or release - InputMethodModeDirect, - - //! Used with proxy widget - InputMethodModeProxy - }; - imState["inputMethodMode"] = InputMethodModeNormal; - - imState["correctionEnabled"] = true; - - valid = true; -} - -void QMaliitPlatformInputContextPrivate::sendStateUpdate(bool focusChanged) -{ - server->updateWidgetInformation(imState, focusChanged); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h b/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h deleted file mode 100644 index 1686983bd7..0000000000 --- a/src/plugins/platforminputcontexts/maliit/qmaliitplatforminputcontext.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QMALIITPLATFORMINPUTCONTEXT_H -#define QMALIITPLATFORMINPUTCONTEXT_H - -#include <qpa/qplatforminputcontext.h> -#include <QDBusArgument> - -QT_BEGIN_NAMESPACE - -class QMaliitPlatformInputContextPrivate; -class QDBusVariant; -class QDBusMessage; - -class QMaliitPlatformInputContext : public QPlatformInputContext -{ - Q_OBJECT -public: - QMaliitPlatformInputContext(); - ~QMaliitPlatformInputContext(); - - bool isValid() const; - - void invokeAction(QInputMethod::Action action, int x); - void reset(void); - void update(Qt::InputMethodQueries); - virtual QRectF keyboardRect() const; - - virtual void showInputPanel(); - virtual void hideInputPanel(); - virtual bool isInputPanelVisible() const; - void setFocusObject(QObject *object); - -public Q_SLOTS: - void activationLostEvent(); - void commitString(const QString &in0, int in1, int in2, int in3); - void updatePreedit(const QDBusMessage &message); - void copy(); - void imInitiatedHide(); - void keyEvent(int type, int key, int modifiers, const QString &text, bool autoRepeat, int count, uchar requestType_); - void paste(); - bool preeditRectangle(int &x, int &y, int &width, int &height); - bool selection(QString &selection); - void setDetectableAutoRepeat(bool in0); - void setGlobalCorrectionEnabled(bool enable); - void setLanguage(const QString &); - void setRedirectKeys(bool ); - void setSelection(int start, int length); - void updateInputMethodArea(int x, int y, int width, int height); - void updateServerWindowOrientation(Qt::ScreenOrientation orientation); - -private: - QMaliitPlatformInputContextPrivate *d; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/platforminputcontexts/maliit/serveraddressproxy.cpp b/src/plugins/platforminputcontexts/maliit/serveraddressproxy.cpp deleted file mode 100644 index 6ff508d66c..0000000000 --- a/src/plugins/platforminputcontexts/maliit/serveraddressproxy.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "serveraddressproxy.h" - -/* - * Implementation of interface class OrgMaliitServerAddressInterface - */ - -OrgMaliitServerAddressInterface::OrgMaliitServerAddressInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) - : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) -{ -} - -OrgMaliitServerAddressInterface::~OrgMaliitServerAddressInterface() -{ -} - diff --git a/src/plugins/platforminputcontexts/maliit/serveraddressproxy.h b/src/plugins/platforminputcontexts/maliit/serveraddressproxy.h deleted file mode 100644 index a9c31de4af..0000000000 --- a/src/plugins/platforminputcontexts/maliit/serveraddressproxy.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SERVERADDRESSPROXY_H -#define SERVERADDRESSPROXY_H - -#include <QtCore/QObject> -#include <QtCore/QByteArray> -#include <QtCore/QList> -#include <QtCore/QMap> -#include <QtCore/QString> -#include <QtCore/QStringList> -#include <QtCore/QVariant> -#include <QtDBus/QtDBus> - -/* - * Proxy class for interface org.maliit.Server.Address - */ -class OrgMaliitServerAddressInterface: public QDBusAbstractInterface -{ - Q_OBJECT -public: - static inline const char *staticInterfaceName() - { return "org.maliit.Server.Address"; } - -public: - OrgMaliitServerAddressInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); - - ~OrgMaliitServerAddressInterface(); - - Q_PROPERTY(QString address READ address) - inline QString address() const - { return qvariant_cast< QString >(property("address")); } - -public Q_SLOTS: // METHODS -Q_SIGNALS: // SIGNALS -}; - -namespace org { - namespace maliit { - namespace Server { - typedef ::OrgMaliitServerAddressInterface Address; - } - } -} -#endif diff --git a/src/plugins/platforminputcontexts/maliit/serverproxy.cpp b/src/plugins/platforminputcontexts/maliit/serverproxy.cpp deleted file mode 100644 index fe104c23f9..0000000000 --- a/src/plugins/platforminputcontexts/maliit/serverproxy.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "serverproxy.h" - -/* - * Implementation of interface class ComMeegoInputmethodUiserver1Interface - */ - -ComMeegoInputmethodUiserver1Interface::ComMeegoInputmethodUiserver1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) - : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) -{ -} - -ComMeegoInputmethodUiserver1Interface::~ComMeegoInputmethodUiserver1Interface() -{ -} - diff --git a/src/plugins/platforminputcontexts/maliit/serverproxy.h b/src/plugins/platforminputcontexts/maliit/serverproxy.h deleted file mode 100644 index e32adfdd94..0000000000 --- a/src/plugins/platforminputcontexts/maliit/serverproxy.h +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SERVER_H_1318935108 -#define SERVER_H_1318935108 - -#include <QtCore/QObject> -#include <QtCore/QByteArray> -#include <QtCore/QList> -#include <QtCore/QMap> -#include <QtCore/QString> -#include <QtCore/QStringList> -#include <QtCore/QVariant> -#include <QtDBus/QtDBus> - -/* - * Proxy class for interface com.meego.inputmethod.uiserver1 - */ -class ComMeegoInputmethodUiserver1Interface: public QDBusAbstractInterface -{ - Q_OBJECT -public: - static inline const char *staticInterfaceName() - { return "com.meego.inputmethod.uiserver1"; } - -public: - ComMeegoInputmethodUiserver1Interface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); - - ~ComMeegoInputmethodUiserver1Interface(); - -public Q_SLOTS: // METHODS - inline QDBusPendingReply<> activateContext() - { - QList<QVariant> argumentList; - return asyncCallWithArgumentList(QLatin1String("activateContext"), argumentList); - } - - inline QDBusPendingReply<> appOrientationAboutToChange(int in0) - { - QList<QVariant> argumentList; - argumentList << QVariant::fromValue(in0); - return asyncCallWithArgumentList(QLatin1String("appOrientationAboutToChange"), argumentList); - } - - inline QDBusPendingReply<> appOrientationChanged(int in0) - { - QList<QVariant> argumentList; - argumentList << QVariant::fromValue(in0); - return asyncCallWithArgumentList(QLatin1String("appOrientationChanged"), argumentList); - } - - inline QDBusPendingReply<> hideInputMethod() - { - QList<QVariant> argumentList; - return asyncCallWithArgumentList(QLatin1String("hideInputMethod"), argumentList); - } - - inline QDBusPendingReply<> mouseClickedOnPreedit(int in0, int in1, int in2, int in3, int in4, int in5) - { - QList<QVariant> argumentList; - argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2) << QVariant::fromValue(in3) << QVariant::fromValue(in4) << QVariant::fromValue(in5); - return asyncCallWithArgumentList(QLatin1String("mouseClickedOnPreedit"), argumentList); - } - - inline QDBusPendingReply<> processKeyEvent(int in0, int in1, int in2, const QString &in3, bool in4, int in5, uint in6, uint in7, uint in8) - { - QList<QVariant> argumentList; - argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1) << QVariant::fromValue(in2) << QVariant::fromValue(in3) << QVariant::fromValue(in4) << QVariant::fromValue(in5) << QVariant::fromValue(in6) << QVariant::fromValue(in7) << QVariant::fromValue(in8); - return asyncCallWithArgumentList(QLatin1String("processKeyEvent"), argumentList); - } - - inline QDBusPendingReply<> setPreedit(const QString &in0, int in1) - { - QList<QVariant> argumentList; - argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); - return asyncCallWithArgumentList(QLatin1String("setPreedit"), argumentList); - } - - inline QDBusPendingReply<> showInputMethod() - { - QList<QVariant> argumentList; - return asyncCallWithArgumentList(QLatin1String("showInputMethod"), argumentList); - } - - inline QDBusPendingReply<> updateWidgetInformation(const QMap<QString, QVariant> &stateInformation, bool focusChanged) - { - QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), "updateWidgetInformation"); - - QDBusArgument map; - map.beginMap(QVariant::String, qMetaTypeId<QDBusVariant>()); - for (QMap<QString, QVariant>::ConstIterator it = stateInformation.constBegin(), end = stateInformation.constEnd(); - it != end; ++it) { - map.beginMapEntry(); - map << it.key(); - map << QDBusVariant(it.value()); - map.endMapEntry(); - } - map.endMap(); - - QList<QVariant> args; - args << QVariant::fromValue(map) << QVariant(focusChanged); - msg.setArguments(args); - return connection().asyncCall(msg); - } - - inline QDBusPendingReply<> reset() - { - return asyncCall(QLatin1String("reset")); - } - - inline QDBusPendingReply<> setCopyPasteState(bool in0, bool in1) - { - QList<QVariant> argumentList; - argumentList << QVariant::fromValue(in0) << QVariant::fromValue(in1); - return asyncCallWithArgumentList(QLatin1String("setCopyPasteState"), argumentList); - } - -Q_SIGNALS: // SIGNALS -}; - -namespace com { - namespace meego { - namespace inputmethod { - typedef ::ComMeegoInputmethodUiserver1Interface uiserver1; - } - } -} -#endif diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro index 733b70be58..60b66bfb35 100644 --- a/src/plugins/platforminputcontexts/platforminputcontexts.pro +++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs qtHaveModule(dbus) { -!mac:!win32:SUBDIRS += ibus maliit +!mac:!win32:SUBDIRS += ibus } unix:!macx:!contains(DEFINES, QT_NO_XKBCOMMON): { diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index 8282b3b558..023cce30ec 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -89,6 +89,9 @@ static AAssetManager *m_assetManager = NULL; static jobject m_resourcesObj; static jobject m_activityObject = NULL; +static bool m_activityActive = true; // defaults to true because when the platform plugin is + // initialized, QtActivity::onResume() has already been called + static jclass m_bitmapClass = 0; static jmethodID m_createBitmapMethodID = 0; static jobject m_ARGB_8888_BitmapConfigValue = 0; @@ -320,6 +323,12 @@ namespace QtAndroid return m_activityObject; } + void setApplicationActive() + { + if (m_activityActive) + QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); + } + jobject createBitmap(QImage img, JNIEnv *env) { if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16) @@ -652,6 +661,16 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/) #endif } +static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state) +{ + m_activityActive = (state == Qt::ApplicationActive); + + if (!m_androidPlatformIntegration) + return; + + QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state)); +} + static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newOrientation) { if (m_androidPlatformIntegration == 0) @@ -678,6 +697,7 @@ static JNINativeMethod methods[] = { {"lockSurface", "()V", (void *)lockSurface}, {"unlockSurface", "()V", (void *)unlockSurface}, {"updateWindow", "()V", (void *)updateWindow}, + {"updateApplicationState", "(I)V", (void *)updateApplicationState}, {"handleOrientationChanged", "(I)V", (void *)handleOrientationChanged} }; diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h index f75df55e02..9a3d8a9607 100644 --- a/src/plugins/platforms/android/src/androidjnimain.h +++ b/src/plugins/platforms/android/src/androidjnimain.h @@ -88,6 +88,8 @@ namespace QtAndroid jclass applicationClass(); jobject activity(); + void setApplicationActive(); + jobject createBitmap(QImage img, JNIEnv *env = 0); jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0); diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp index 24a7debd1f..f9262c69f6 100644 --- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp @@ -120,6 +120,12 @@ void QAndroidOpenGLPlatformWindow::raise() void QAndroidOpenGLPlatformWindow::setVisible(bool visible) { QEglFSWindow::setVisible(visible); + + // The Android Activity is activated before Qt is initialized, causing the application state to + // never be set to 'active'. We explicitly set this state when the first window becomes visible. + if (visible) + QtAndroid::setApplicationActive(); + QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event QWindowSystemInterface::flushWindowSystemEvents(); } diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index 3e7b046edb..045eb57148 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -121,6 +121,7 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const { switch (cap) { case ThreadedPixmaps: return true; + case ApplicationState: return true; case NonFullScreenWindows: return false; case NativeWidgets: return false; default: diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp index 94a69c10c7..f5fce0ae34 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp @@ -41,6 +41,9 @@ #include "qandroidplatformwindow.h" +#include "androidjnimain.h" +#include <qpa/qwindowsysteminterface.h> + QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window) { } @@ -54,3 +57,13 @@ void QAndroidPlatformWindow::propagateSizeHints() { //shut up warning from default implementation } + +void QAndroidPlatformWindow::setVisible(bool visible) +{ + QFbWindow::setVisible(visible); + + // The Android Activity is activated before Qt is initialized, causing the application state to + // never be set to 'active'. We explicitly set this state when the first window becomes visible. + if (visible) + QtAndroid::setApplicationActive(); +} diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h index 3ee815fd69..58e6451ea1 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h @@ -52,6 +52,8 @@ public: void propagateSizeHints(); + void setVisible(bool visible); + public slots: void setGeometry(const QRect &rect); diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h index 49ddf3106b..4c08a664d8 100644 --- a/src/plugins/platforms/windows/qtwindows_additional.h +++ b/src/plugins/platforms/windows/qtwindows_additional.h @@ -49,6 +49,10 @@ # define WM_THEMECHANGED 0x031A #endif +#ifndef WM_DWMCOMPOSITIONCHANGED +# define WM_DWMCOMPOSITIONCHANGED 0x31E +#endif + #ifndef GWL_HWNDPARENT # define GWL_HWNDPARENT (-8) #endif diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index 64bf1d71ca..e9eb50799e 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -105,6 +105,7 @@ enum WindowsEventType // Simplify event types InputMethodCloseCandidateWindowEvent = InputMethodEventFlag + 5, InputMethodRequest = InputMethodEventFlag + 6, ThemeChanged = ThemingEventFlag + 1, + CompositionSettingsChanged = ThemingEventFlag + 2, DisplayChangedEvent = 437, SettingChangedEvent = DisplayChangedEvent + 1, ContextMenu = 123, @@ -201,6 +202,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI return QtWindows::DisplayChangedEvent; case WM_THEMECHANGED: return QtWindows::ThemeChanged; + case WM_DWMCOMPOSITIONCHANGED: + return QtWindows::CompositionSettingsChanged; #ifndef QT_NO_CONTEXTMENU case WM_CONTEXTMENU: return QtWindows::ContextMenu; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 132b3684e9..c676ca3c46 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -884,6 +884,9 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, theme->windowsThemeChanged(platformWindow->window()); return true; } + case QtWindows::CompositionSettingsChanged: + platformWindow->handleCompositionSettingsChanged(); + return true; #ifndef Q_OS_WINCE case QtWindows::ActivateWindowEvent: #ifndef QT_NO_TABLETEVENT diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index ace18ddf5b..f3faccbc14 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -56,6 +56,7 @@ #include <QtGui/QScreen> #include <QtGui/QWindow> #include <QtGui/QRegion> +#include <private/qsystemlibrary_p.h> #include <private/qwindow_p.h> #include <private/qguiapplication_p.h> #include <qpa/qwindowsysteminterface.h> @@ -203,6 +204,69 @@ static inline QSize clientSize(HWND hwnd) return qSizeOfRect(rect); } +static bool applyBlurBehindWindow(HWND hwnd) +{ +#ifdef Q_OS_WINCE + Q_UNUSED(hwnd); + return false; +#else + enum { dwmBbEnable = 0x1, dwmBbBlurRegion = 0x2 }; + + struct DwmBlurBehind { + DWORD dwFlags; + BOOL fEnable; + HRGN hRgnBlur; + BOOL fTransitionOnMaximized; + }; + + typedef HRESULT (WINAPI *PtrDwmEnableBlurBehindWindow)(HWND, const DwmBlurBehind*); + typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL *); + + // DWM API is available only from Windows Vista + if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA) + return false; + + static bool functionPointersResolved = false; + static PtrDwmEnableBlurBehindWindow dwmBlurBehind = 0; + static PtrDwmIsCompositionEnabled dwmIsCompositionEnabled = 0; + + if (Q_UNLIKELY(!functionPointersResolved)) { + QSystemLibrary library(QStringLiteral("dwmapi")); + if (library.load()) { + dwmBlurBehind = (PtrDwmEnableBlurBehindWindow)(library.resolve("DwmEnableBlurBehindWindow")); + dwmIsCompositionEnabled = (PtrDwmIsCompositionEnabled)(library.resolve("DwmIsCompositionEnabled")); + } + + functionPointersResolved = true; + } + + if (Q_UNLIKELY(!dwmBlurBehind || !dwmIsCompositionEnabled)) + return false; + + BOOL compositionEnabled; + if (dwmIsCompositionEnabled(&compositionEnabled) != S_OK) + return false; + + DwmBlurBehind blurBehind = {0, 0, 0, 0}; + + if (compositionEnabled) { + blurBehind.dwFlags = dwmBbEnable | dwmBbBlurRegion; + blurBehind.fEnable = TRUE; + blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1); + } else { + blurBehind.dwFlags = dwmBbEnable; + blurBehind.fEnable = FALSE; + } + + const bool result = dwmBlurBehind(hwnd, &blurBehind) == S_OK; + + if (blurBehind.hRgnBlur) + DeleteObject(blurBehind.hRgnBlur); + + return result; +#endif // Q_OS_WINCE +} + // from qwidget_win.cpp, pass flags separately in case they have been "autofixed". static bool shouldShowMaximizeButton(const QWindow *w, Qt::WindowFlags flags) { @@ -543,6 +607,10 @@ QWindowsWindow::WindowData result.frame = context->margins; result.embedded = embedded; result.customMargins = context->customMargins; + + if (isGL && hasAlpha) + applyBlurBehindWindow(result.hwnd); + return result; } @@ -1167,6 +1235,13 @@ void QWindowsWindow::handleHidden() fireExpose(QRegion()); } +void QWindowsWindow::handleCompositionSettingsChanged() +{ + const QWindow *w = window(); + if (w->surfaceType() == QWindow::OpenGLSurface && w->format().hasAlpha()) + applyBlurBehindWindow(handle()); +} + void QWindowsWindow::setGeometry(const QRect &rectIn) { QRect rect = rectIn; diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index afcfa8b821..f055864482 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -221,6 +221,7 @@ public: void handleMoved(); void handleResized(int wParam); void handleHidden(); + void handleCompositionSettingsChanged(); static inline HWND handleOf(const QWindow *w); static inline QWindowsWindow *baseWindowOf(const QWindow *w); diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 697c8f5574..dd5189758d 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -84,6 +84,8 @@ SOURCES += \ ../../corelib/tools/qbytearray.cpp \ ../../corelib/tools/qarraydata.cpp \ ../../corelib/tools/qbytearraymatcher.cpp \ + ../../corelib/tools/qcommandlineparser.cpp \ + ../../corelib/tools/qcommandlineoption.cpp \ ../../corelib/tools/qcryptographichash.cpp \ ../../corelib/tools/qdatetime.cpp \ ../../corelib/tools/qhash.cpp \ diff --git a/src/tools/qdoc/qmlparser/qqmljs.g b/src/tools/qdoc/qmlparser/qqmljs.g index ff4f54374b..7ba6859534 100644 --- a/src/tools/qdoc/qmlparser/qqmljs.g +++ b/src/tools/qdoc/qmlparser/qqmljs.g @@ -316,7 +316,7 @@ public: inline DiagnosticMessage diagnosticMessage() const { foreach (const DiagnosticMessage &d, diagnostic_messages) { - if (! d.kind == DiagnosticMessage::Warning) + if (d.kind != DiagnosticMessage::Warning) return d; } diff --git a/src/tools/qdoc/qmlparser/qqmljsparser_p.h b/src/tools/qdoc/qmlparser/qqmljsparser_p.h index 1b13690547..6edfd844d0 100644 --- a/src/tools/qdoc/qmlparser/qqmljsparser_p.h +++ b/src/tools/qdoc/qmlparser/qqmljsparser_p.h @@ -175,7 +175,7 @@ public: inline DiagnosticMessage diagnosticMessage() const { foreach (const DiagnosticMessage &d, diagnostic_messages) { - if (! d.kind == DiagnosticMessage::Warning) + if (d.kind != DiagnosticMessage::Warning) return d; } diff --git a/src/tools/qdoc/tokenizer.cpp b/src/tools/qdoc/tokenizer.cpp index 224d451f4c..e1ca28eef8 100644 --- a/src/tools/qdoc/tokenizer.cpp +++ b/src/tools/qdoc/tokenizer.cpp @@ -237,7 +237,11 @@ int Tokenizer::getToken() return getTokenAfterPreprocessor(); case '&': yyCh = getChar(); - if (yyCh == '&' || yyCh == '=') { + /* + Removed check for '&&', only interpret '&=' as an operator. + '&&' is also used for an rvalue reference. QTBUG-32675 + */ + if (yyCh == '=') { yyCh = getChar(); return Tok_SomeOperator; } diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp index 6b311a8e55..510a552c12 100644 --- a/src/tools/rcc/main.cpp +++ b/src/tools/rcc/main.cpp @@ -49,31 +49,12 @@ #include <qtextstream.h> #include <qatomic.h> #include <qglobal.h> +#include <qcoreapplication.h> +#include <qcommandlineoption.h> +#include <qcommandlineparser.h> -QT_BEGIN_NAMESPACE -void showHelp(const QString &argv0, const QString &error) -{ - fprintf(stderr, "Qt resource compiler\n"); - if (!error.isEmpty()) - fprintf(stderr, "%s: %s\n", qPrintable(argv0), qPrintable(error)); - fprintf(stderr, "Usage: %s [options] <inputs>\n\n" - "Options:\n" - " -o file write output to file rather than stdout\n" - " -name name create an external initialization function with name\n" - " -threshold level threshold to consider compressing files\n" - " -compress level compress input files by level\n" - " -root path prefix resource access path with root path\n" - " -no-compress disable all compression\n" - " -binary output a binary file for use as a dynamic resource\n" - " -namespace turn off namespace macros\n" - " -project Output a resource file containing all\n" - " files from the current directory\n" - " -list lists .qrc file entries\n" - " -version display version\n" - " -help display this information\n", - qPrintable(argv0)); -} +QT_BEGIN_NAMESPACE void dumpRecursive(const QDir &dir, QTextStream &out) { @@ -127,92 +108,103 @@ int createProject(const QString &outFileName) int runRcc(int argc, char *argv[]) { - QString outFilename; - bool helpRequested = false; - bool list = false; - bool projectRequested = false; - QStringList filenamesIn; + QCoreApplication app(argc, argv); + QCoreApplication::setApplicationVersion(QString::fromLatin1(QT_VERSION_STR)); - QStringList args = qCmdLineArgs(argc, argv); + // Note that rcc isn't translated. + // If you use this code as an example for a translated app, make sure to translate the strings. + QCommandLineParser parser; + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.setApplicationDescription(QStringLiteral("Qt Resource Compiler version %1").arg(QString::fromLatin1(QT_VERSION_STR))); + parser.addHelpOption(); + parser.addVersionOption(); + + QCommandLineOption outputOption(QStringList() << QStringLiteral("o") << QStringLiteral("output")); + outputOption.setDescription(QStringLiteral("Write output to <file> rather than stdout.")); + outputOption.setValueName(QStringLiteral("file")); + parser.addOption(outputOption); + + QCommandLineOption nameOption(QStringLiteral("name"), QStringLiteral("Create an external initialization function with <name>."), QStringLiteral("name")); + parser.addOption(nameOption); + + QCommandLineOption rootOption(QStringLiteral("root"), QStringLiteral("Prefix resource access path with root path."), QStringLiteral("path")); + parser.addOption(rootOption); + + QCommandLineOption compressOption(QStringLiteral("compress"), QStringLiteral("Compress input files by <level>."), QStringLiteral("level")); + parser.addOption(compressOption); + + QCommandLineOption nocompressOption(QStringLiteral("no-compress"), QStringLiteral("Disable all compression.")); + parser.addOption(nocompressOption); + + QCommandLineOption thresholdOption(QStringLiteral("threshold"), QStringLiteral("Threshold to consider compressing files."), QStringLiteral("level")); + parser.addOption(thresholdOption); + + QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource.")); + parser.addOption(binaryOption); + + QCommandLineOption namespaceOption(QStringLiteral("namespace"), QStringLiteral("Turn off namespace macros.")); + parser.addOption(namespaceOption); + + QCommandLineOption verboseOption(QStringLiteral("verbose"), QStringLiteral("Enable verbose mode.")); + parser.addOption(verboseOption); + + QCommandLineOption listOption(QStringLiteral("list"), QStringLiteral("Only list .qrc file entries, do not generate code.")); + parser.addOption(listOption); + + QCommandLineOption projectOption(QStringLiteral("project"), QStringLiteral("Output a resource file containing all files from the current directory.")); + parser.addOption(projectOption); + + parser.addPositionalArgument(QStringLiteral("inputs"), QStringLiteral("Input files (*.qrc).")); - RCCResourceLibrary library; //parse options + parser.process(app); + QString errorMsg; - for (int i = 1; i < args.count() && errorMsg.isEmpty(); i++) { - if (args[i].isEmpty()) - continue; - if (args[i][0] == QLatin1Char('-')) { // option - QString opt = args[i]; - if (opt == QLatin1String("-o")) { - if (!(i < argc-1)) { - errorMsg = QLatin1String("Missing output name"); - break; - } - outFilename = args[++i]; - } else if (opt == QLatin1String("-name")) { - if (!(i < argc-1)) { - errorMsg = QLatin1String("Missing target name"); - break; - } - library.setInitName(args[++i]); - } else if (opt == QLatin1String("-root")) { - if (!(i < argc-1)) { - errorMsg = QLatin1String("Missing root path"); - break; - } - library.setResourceRoot(QDir::cleanPath(args[++i])); - if (library.resourceRoot().isEmpty() - || library.resourceRoot().at(0) != QLatin1Char('/')) - errorMsg = QLatin1String("Root must start with a /"); - } else if (opt == QLatin1String("-compress")) { - if (!(i < argc-1)) { - errorMsg = QLatin1String("Missing compression level"); - break; - } - library.setCompressLevel(args[++i].toInt()); - } else if (opt == QLatin1String("-threshold")) { - if (!(i < argc-1)) { - errorMsg = QLatin1String("Missing compression threshold"); - break; - } - library.setCompressThreshold(args[++i].toInt()); - } else if (opt == QLatin1String("-binary")) { - library.setFormat(RCCResourceLibrary::Binary); - } else if (opt == QLatin1String("-namespace")) { - library.setUseNameSpace(!library.useNameSpace()); - } else if (opt == QLatin1String("-verbose")) { - library.setVerbose(true); - } else if (opt == QLatin1String("-list")) { - list = true; - } else if (opt == QLatin1String("-version") || opt == QLatin1String("-v")) { - fprintf(stderr, "Qt Resource Compiler version %s\n", QT_VERSION_STR); - return 1; - } else if (opt == QLatin1String("-help") || opt == QLatin1String("-h")) { - helpRequested = true; - } else if (opt == QLatin1String("-no-compress")) { - library.setCompressLevel(-2); - } else if (opt == QLatin1String("-project")) { - projectRequested = true; - } else { - errorMsg = QString::fromLatin1("Unknown option: '%1'").arg(args[i]); - } - } else { - if (!QFile::exists(args[i])) { - qWarning("%s: File does not exist '%s'", - qPrintable(args[0]), qPrintable(args[i])); - return 1; - } - filenamesIn.append(args[i]); + RCCResourceLibrary library; + QString outFilename = parser.value(outputOption); + if (parser.isSet(nameOption)) + library.setInitName(parser.value(nameOption)); + if (parser.isSet(rootOption)) { + library.setResourceRoot(QDir::cleanPath(parser.value(rootOption))); + if (library.resourceRoot().isEmpty() + || library.resourceRoot().at(0) != QLatin1Char('/')) + errorMsg = QLatin1String("Root must start with a /"); + } + if (parser.isSet(compressOption)) + library.setCompressLevel(parser.value(compressOption).toInt()); + if (parser.isSet(nocompressOption)) + library.setCompressLevel(-2); + if (parser.isSet(thresholdOption)) + library.setCompressThreshold(parser.value(thresholdOption).toInt()); + if (parser.isSet(binaryOption)) + library.setFormat(RCCResourceLibrary::Binary); + if (parser.isSet(namespaceOption)) + library.setUseNameSpace(!library.useNameSpace()); + if (parser.isSet(verboseOption)) + library.setVerbose(true); + + const bool list = parser.isSet(listOption); + const bool projectRequested = parser.isSet(projectOption); + const QStringList filenamesIn = parser.positionalArguments(); + + foreach (const QString &file, filenamesIn) { + if (!QFile::exists(file)) { + qWarning("%s: File does not exist '%s'", argv[0], qPrintable(file)); + return 1; } } - if (projectRequested && !helpRequested) { + if (projectRequested) { return createProject(outFilename); } - if (!filenamesIn.size() || !errorMsg.isEmpty() || helpRequested) { - showHelp(args[0], errorMsg); + if (filenamesIn.isEmpty()) + errorMsg = QStringLiteral("No input files specified."); + + if (!errorMsg.isEmpty()) { + fprintf(stderr, "%s: %s\n", argv[0], qPrintable(errorMsg)); + parser.showHelp(1); return 1; } QFile errorDevice; diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp index a25a40052e..c29292a99b 100644 --- a/src/tools/uic/main.cpp +++ b/src/tools/uic/main.cpp @@ -47,94 +47,75 @@ #include <qdir.h> #include <qtextstream.h> #include <qtextcodec.h> +#include <qcoreapplication.h> +#include <qcommandlineoption.h> +#include <qcommandlineparser.h> QT_BEGIN_NAMESPACE -static const char *error = 0; - -void showHelp(const char *appName) -{ - fprintf(stderr, "Qt User Interface Compiler version %s\n", QT_VERSION_STR); - if (error) - fprintf(stderr, "%s: %s\n", appName, error); - - fprintf(stderr, "Usage: %s [options] <uifile>\n\n" - " -h, -help display this help and exit\n" - " -v, -version display version\n" - " -d, -dependencies display the dependencies\n" - " -o <file> place the output into <file>\n" - " -tr <func> use func() for i18n\n" - " -p, -no-protection disable header protection\n" - " -n, -no-implicit-includes disable generation of #include-directives\n" - " for forms generated by uic3\n" - " -g <name> change generator\n" - "\n", appName); -} - int runUic(int argc, char *argv[]) { - Driver driver; + QCoreApplication app(argc, argv); + QCoreApplication::setApplicationVersion(QString::fromLatin1(QT_VERSION_STR)); - const char *fileName = 0; - - int arg = 1; - while (arg < argc) { - QString opt = QString::fromLocal8Bit(argv[arg]); - if (opt == QLatin1String("-h") || opt == QLatin1String("-help")) { - showHelp(argv[0]); - return 0; - } else if (opt == QLatin1String("-d") || opt == QLatin1String("-dependencies")) { - driver.option().dependencies = true; - } else if (opt == QLatin1String("-v") || opt == QLatin1String("-version")) { - fprintf(stderr, "Qt User Interface Compiler version %s\n", QT_VERSION_STR); - return 0; - } else if (opt == QLatin1String("-o") || opt == QLatin1String("-output")) { - ++arg; - if (!argv[arg]) { - showHelp(argv[0]); - return 1; - } - driver.option().outputFile = QFile::decodeName(argv[arg]); - } else if (opt == QLatin1String("-p") || opt == QLatin1String("-no-protection")) { - driver.option().headerProtection = false; - } else if (opt == QLatin1String("-n") || opt == QLatin1String("-no-implicit-includes")) { - driver.option().implicitIncludes = false; - } else if (opt == QLatin1String("-postfix")) { - ++arg; - if (!argv[arg]) { - showHelp(argv[0]); - return 1; - } - driver.option().postfix = QLatin1String(argv[arg]); - } else if (opt == QLatin1String("-tr") || opt == QLatin1String("-translate")) { - ++arg; - if (!argv[arg]) { - showHelp(argv[0]); - return 1; - } - driver.option().translateFunction = QLatin1String(argv[arg]); - } else if (opt == QLatin1String("-g") || opt == QLatin1String("-generator")) { - ++arg; - if (!argv[arg]) { - showHelp(argv[0]); - return 1; - } - QString name = QString::fromLocal8Bit(argv[arg]).toLower (); - driver.option().generator = (name == QLatin1String ("java")) ? Option::JavaGenerator : Option::CppGenerator; - } else if (!fileName) { - fileName = argv[arg]; - } else { - showHelp(argv[0]); - return 1; - } + Driver driver; - ++arg; - } + // Note that uic isn't translated. + // If you use this code as an example for a translated app, make sure to translate the strings. + QCommandLineParser parser; + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.setApplicationDescription(QStringLiteral("Qt User Interface Compiler version %1").arg(QString::fromLatin1(QT_VERSION_STR))); + parser.addHelpOption(); + parser.addVersionOption(); + + QCommandLineOption dependenciesOption(QStringList() << QStringLiteral("d") << QStringLiteral("dependencies")); + dependenciesOption.setDescription(QStringLiteral("Display the dependencies.")); + parser.addOption(dependenciesOption); + + QCommandLineOption outputOption(QStringList() << QStringLiteral("o") << QStringLiteral("output")); + outputOption.setDescription(QStringLiteral("Place the output into <file>")); + outputOption.setValueName(QStringLiteral("file")); + parser.addOption(outputOption); + + QCommandLineOption noProtOption(QStringList() << QStringLiteral("p") << QStringLiteral("no-protection")); + noProtOption.setDescription(QStringLiteral("Disable header protection.")); + parser.addOption(noProtOption); + + QCommandLineOption noImplicitIncludesOption(QStringList() << QStringLiteral("n") << QStringLiteral("no-implicit-includes")); + noImplicitIncludesOption.setDescription(QStringLiteral("Disable generation of #include-directives.")); + parser.addOption(noImplicitIncludesOption); + + QCommandLineOption postfixOption(QStringLiteral("postfix")); + postfixOption.setDescription(QStringLiteral("Postfix to add to all generated classnames.")); + postfixOption.setValueName(QStringLiteral("postfix")); + parser.addOption(postfixOption); + + QCommandLineOption translateOption(QStringList() << QStringLiteral("tr") << QStringLiteral("translate")); + translateOption.setDescription(QStringLiteral("Use <function> for i18n.")); + translateOption.setValueName(QStringLiteral("function")); + parser.addOption(translateOption); + + QCommandLineOption generatorOption(QStringList() << QStringLiteral("g") << QStringLiteral("generator")); + generatorOption.setDescription(QStringLiteral("Select generator.")); + generatorOption.setValueName(QStringLiteral("java|cpp")); + parser.addOption(generatorOption); + + parser.addPositionalArgument(QStringLiteral("[uifile]"), QStringLiteral("Input file (*.ui), otherwise stdin.")); + + parser.process(app); + + driver.option().dependencies = parser.isSet(dependenciesOption); + driver.option().outputFile = parser.value(outputOption); + driver.option().headerProtection = !parser.isSet(noProtOption); + driver.option().implicitIncludes = !parser.isSet(noImplicitIncludesOption); + driver.option().postfix = parser.value(postfixOption); + driver.option().translateFunction = parser.value(translateOption); + driver.option().generator = (parser.value(generatorOption).toLower() == QLatin1String("java")) ? Option::JavaGenerator : Option::CppGenerator; QString inputFile; - if (fileName) - inputFile = QString::fromLocal8Bit(fileName); - else + if (!parser.positionalArguments().isEmpty()) + inputFile = parser.positionalArguments().first(); + else // reading from stdin driver.option().headerProtection = false; if (driver.option().dependencies) { diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 9c4b99253a..62cec34b2b 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -57,6 +57,7 @@ #include <stdlib.h> #include <qsettings.h> #include <qdebug.h> +#include <qmimedatabase.h> #include <qapplication.h> #include <qstylepainter.h> #if !defined(Q_OS_WINCE) @@ -1441,6 +1442,75 @@ void QFileDialog::setFilter(QDir::Filters filters) d->showHiddenAction->setChecked((filters & QDir::Hidden)); } +static QString nameFilterForMime(const QString &mimeType) +{ + QMimeDatabase db; + QMimeType mime(db.mimeTypeForName(mimeType)); + if (mime.isValid()) { + if (mime.isDefault()) { + return QFileDialog::tr("All files (*)"); + } else { + const QString patterns = mime.globPatterns().join(QLatin1Char(' ')); + return mime.comment() + QStringLiteral(" (") + patterns + QLatin1Char(')'); + } + } + return QString(); +} + +/*! + \since 5.2 + + Sets the \a filters used in the file dialog, from a list of MIME types. + + Convenience method for setNameFilters(). + Uses QMimeType to create a name filter from the glob patterns and description + defined in each MIME type. + + Use application/octet-stream for the "All files (*)" filter, since that + is the base MIME type for all files. + + Calling setMimeTypeFilters overrides any previously set name filters, + and changes the return value of nameFilters(). + + \snippet code/src_gui_dialogs_qfiledialog.cpp 13 +*/ +void QFileDialog::setMimeTypeFilters(const QStringList &filters) +{ + Q_D(QFileDialog); + QStringList nameFilters; + foreach (const QString &mimeType, filters) { + const QString text = nameFilterForMime(mimeType); + if (!text.isEmpty()) + nameFilters.append(text); + } + setNameFilters(nameFilters); + d->options->setMimeTypeFilters(filters); +} + +/*! + \since 5.2 + + Returns the MIME type filters that are in operation on this file + dialog. +*/ +QStringList QFileDialog::mimeTypeFilters() const +{ + return d_func()->options->mimeTypeFilters(); +} + +/*! + \since 5.2 + + Sets the current MIME type \a filter. + +*/ +void QFileDialog::selectMimeTypeFilter(const QString &filter) +{ + const QString text = nameFilterForMime(filter); + if (!text.isEmpty()) + selectNameFilter(text); +} + /*! \property QFileDialog::viewMode \brief the way files and directories are displayed in the dialog diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h index 5413a42ea9..404e16cde1 100644 --- a/src/widgets/dialogs/qfiledialog.h +++ b/src/widgets/dialogs/qfiledialog.h @@ -124,6 +124,10 @@ public: void selectNameFilter(const QString &filter); QString selectedNameFilter() const; + void setMimeTypeFilters(const QStringList &filters); + QStringList mimeTypeFilters() const; + void selectMimeTypeFilter(const QString &filter); + QDir::Filters filter() const; void setFilter(QDir::Filters filters); diff --git a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp index a253c09d8b..f0010b6f25 100644 --- a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp +++ b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp @@ -129,3 +129,14 @@ QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); //! [12] + +//! [13] +QStringList mimeTypeFilters; +mimeTypeFilters << "image/jpeg" // will show "JPEG image (*.jpeg *.jpg *.jpe) + << "image/png" // will show "PNG image (*.png)" + << "application/octet-stream"; // will show "All files (*)" + +QFileDialog dialog(this); +dialog.setMimeTypeFilters(mimeTypeFilters); +dialog.exec(); +//! [13] diff --git a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp index f70e66f685..7598163f2d 100644 --- a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -567,10 +567,7 @@ QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co itemList << item; } } - if (order != -1) { - //We sort descending order - d->sortItems(&itemList, order, d->sortCacheEnabled); - } + d->sortItems(&itemList, order, d->sortCacheEnabled); return itemList; } diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 32c63b9f93..8dbbd16f62 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1833,7 +1833,7 @@ void QCommonListViewBase::removeHiddenRow(int row) dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex())); } -void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step) +void QCommonListViewBase::updateHorizontalScrollBar(const QSize & /*step*/) { horizontalScrollBar()->setPageStep(viewport()->width()); horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width()); diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 54b663274d..e4c2cfcb0c 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -2179,10 +2179,10 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie if (!current.isValid()) { int i = d->below(-1); int c = 0; - while (c < d->header->count() && d->header->isSectionHidden(c)) + while (c < d->header->count() && d->header->isSectionHidden(d->header->logicalIndex(c))) ++c; if (i < d->viewItems.count() && c < d->header->count()) { - return d->modelIndex(i, c); + return d->modelIndex(i, d->header->logicalIndex(c)); } return QModelIndex(); } diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index be89abf2b2..7b4b882e56 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -1096,7 +1096,7 @@ void QRenderRule::fixupBorder(int nativeWidth) bd->borders[i] = nativeWidth; // intentional fall through default: - if (!bd->colors[i].style() != Qt::NoBrush) // auto-acquire 'color' + if (bd->colors[i].style() == Qt::NoBrush) // auto-acquire 'color' bd->colors[i] = color; break; } diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index 3f9b28a883..be712f0747 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -575,6 +575,20 @@ void QAbstractButtonPrivate::emitReleased() #endif } +void QAbstractButtonPrivate::emitToggled(bool checked) +{ + Q_Q(QAbstractButton); + QPointer<QAbstractButton> guard(q); + emit q->toggled(checked); +#ifndef QT_NO_BUTTONGROUP + if (guard && group) { + emit group->buttonToggled(group->id(q), checked); + if (guard && group) + emit group->buttonToggled(q, checked); + } +#endif +} + /*! Constructs an abstract button with a \a parent. */ @@ -758,7 +772,7 @@ void QAbstractButton::setChecked(bool checked) if (guard && checked) d->notifyChecked(); if (guard) - emit toggled(checked); + d->emitToggled(checked); #ifndef QT_NO_ACCESSIBILITY diff --git a/src/widgets/widgets/qabstractbutton_p.h b/src/widgets/widgets/qabstractbutton_p.h index 4585728848..a148e60717 100644 --- a/src/widgets/widgets/qabstractbutton_p.h +++ b/src/widgets/widgets/qabstractbutton_p.h @@ -103,6 +103,7 @@ public: void emitPressed(); void emitReleased(); void emitClicked(); + void emitToggled(bool checked); }; QT_END_NAMESPACE diff --git a/src/widgets/widgets/qbuttongroup.cpp b/src/widgets/widgets/qbuttongroup.cpp index f22910007f..c484b154fd 100644 --- a/src/widgets/widgets/qbuttongroup.cpp +++ b/src/widgets/widgets/qbuttongroup.cpp @@ -174,6 +174,27 @@ */ /*! + \fn void QButtonGroup::buttonToggled(QAbstractButton *button, bool checked) + \since 5.2 + + This signal is emitted when the given \a button is toggled. + \a checked is true if the button is checked, or false if the button is unchecked. + + \sa QAbstractButton::toggled() +*/ + +/*! + \fn void QButtonGroup::buttonToggled(int id, bool checked) + \since 5.2 + + This signal is emitted when a button with the given \a id is toggled. + \a checked is true if the button is checked, or false if the button is unchecked. + + \sa QAbstractButton::toggled() +*/ + + +/*! \fn void QButtonGroup::addButton(QAbstractButton *button, int id = -1); Adds the given \a button to the button group. If \a id is -1, diff --git a/src/widgets/widgets/qbuttongroup.h b/src/widgets/widgets/qbuttongroup.h index 84fe26e0df..06656bf18c 100644 --- a/src/widgets/widgets/qbuttongroup.h +++ b/src/widgets/widgets/qbuttongroup.h @@ -85,7 +85,8 @@ Q_SIGNALS: void buttonPressed(int); void buttonReleased(QAbstractButton *); void buttonReleased(int); - + void buttonToggled(QAbstractButton *, bool); + void buttonToggled(int, bool); private: Q_DISABLE_COPY(QButtonGroup) diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp index 3607467ff9..a6d76ea7b6 100644 --- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp @@ -269,7 +269,8 @@ static int NColorRoles[] = { QPalette::ToolTipText + 1, // Qt_4_6 QPalette::ToolTipText + 1, // Qt_5_0 QPalette::ToolTipText + 1, // Qt_5_1 - 0 // add the correct value for Qt_5_2 here later + QPalette::ToolTipText + 1, // Qt_5_2 + 0 // add the correct value for Qt_5_3 here later }; // Testing get/set functions diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 7a3f6837f8..8965c0787e 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -122,6 +122,7 @@ private slots: void setStandardInputFile(); void setStandardOutputFile_data(); void setStandardOutputFile(); + void setStandardOutputFile2(); void setStandardOutputProcess_data(); void setStandardOutputProcess(); void removeFileWhileProcessIsRunning(); @@ -1868,6 +1869,13 @@ void tst_QProcess::setStandardInputFile() QByteArray all = process.readAll(); QCOMPARE(all.size(), int(sizeof data) - 1); // testProcessEcho drops the ending \0 QVERIFY(all == data); + + QProcess process2; + process2.setStandardInputFile(QProcess::nullDevice()); + process2.start("testProcessEcho/testProcessEcho"); + QPROCESS_VERIFY(process2, waitForFinished()); + all = process2.readAll(); + QCOMPARE(all.size(), 0); } #endif @@ -1902,6 +1910,23 @@ void tst_QProcess::setStandardOutputFile_data() << true; } +//----------------------------------------------------------------------------- +#ifndef Q_OS_WINCE +void tst_QProcess::setStandardOutputFile2() +{ + static const char testdata[] = "Test data."; + + QProcess process; + process.setStandardOutputFile(QProcess::nullDevice()); + process.start("testProcessEcho2/testProcessEcho2"); + process.write(testdata, sizeof testdata); + QPROCESS_VERIFY(process,waitForFinished()); + QVERIFY(!process.bytesAvailable()); + + QVERIFY(!QFileInfo(QProcess::nullDevice()).isFile()); +} +#endif + void tst_QProcess::setStandardOutputFile() { static const char data[] = "Original data. "; diff --git a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp index 45f143b9fb..9d3519680c 100644 --- a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp +++ b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp @@ -43,10 +43,6 @@ #include <QObject> #include <QProcessEnvironment> -#ifdef QT_NO_PROCESS -QTEST_NOOP_MAIN -#else - class tst_QProcessEnvironment: public QObject { Q_OBJECT @@ -322,4 +318,3 @@ void tst_QProcessEnvironment::putenv() QTEST_MAIN(tst_QProcessEnvironment) #include "tst_qprocessenvironment.moc" -#endif diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index cdf240d757..4a9932798c 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -638,6 +638,7 @@ void tst_QThreadPool::reserveAndStart() // QTBUG-21051 public: QAtomicInt count; QSemaphore waitForStarted; + QSemaphore waitBeforeDone; WaitingTask() { setAutoDelete(false); } @@ -645,6 +646,7 @@ void tst_QThreadPool::reserveAndStart() // QTBUG-21051 { count.ref(); waitForStarted.release(); + waitBeforeDone.acquire(); } }; @@ -663,6 +665,7 @@ void tst_QThreadPool::reserveAndStart() // QTBUG-21051 threadpool->start(task); QCOMPARE(threadpool->activeThreadCount(), 2); task->waitForStarted.acquire(); + task->waitBeforeDone.release(); QTRY_COMPARE(task->count.load(), 1); QTRY_COMPARE(threadpool->activeThreadCount(), 1); @@ -675,6 +678,7 @@ void tst_QThreadPool::reserveAndStart() // QTBUG-21051 threadpool->start(task); QTRY_COMPARE(threadpool->activeThreadCount(), 2); task->waitForStarted.acquire(); + task->waitBeforeDone.release(); QTRY_COMPARE(task->count.load(), 2); QTRY_COMPARE(threadpool->activeThreadCount(), 1); diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 50092c9989..5576d3d8a4 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -129,8 +129,9 @@ private slots: void fromStringToStringLocale_data(); void fromStringToStringLocale(); - void utcOffset(); - void setUtcOffset(); + void offsetFromUtc(); + void setOffsetFromUtc(); + void toOffsetFromUtc(); void getDate(); @@ -187,8 +188,11 @@ QDateTime tst_QDateTime::dt( const QString& str ) void tst_QDateTime::ctor() { QDateTime dt1(QDate(2004, 1, 2), QTime(1, 2, 3)); + QCOMPARE(dt1.timeSpec(), Qt::LocalTime); QDateTime dt2(QDate(2004, 1, 2), QTime(1, 2, 3), Qt::LocalTime); + QCOMPARE(dt2.timeSpec(), Qt::LocalTime); QDateTime dt3(QDate(2004, 1, 2), QTime(1, 2, 3), Qt::UTC); + QCOMPARE(dt3.timeSpec(), Qt::UTC); QVERIFY(dt1 == dt2); if (europeanTimeZone) { @@ -196,6 +200,34 @@ void tst_QDateTime::ctor() QVERIFY(dt1 < dt3); QVERIFY(dt1.addSecs(3600).toUTC() == dt3); } + + // Test OffsetFromUTC constructors + QDate offsetDate(2013, 1, 1); + QTime offsetTime(1, 2, 3); + + QDateTime offset1(offsetDate, offsetTime, Qt::OffsetFromUTC); + QCOMPARE(offset1.timeSpec(), Qt::UTC); + QCOMPARE(offset1.offsetFromUtc(), 0); + QCOMPARE(offset1.date(), offsetDate); + QCOMPARE(offset1.time(), offsetTime); + + QDateTime offset2(offsetDate, offsetTime, Qt::OffsetFromUTC, 0); + QCOMPARE(offset2.timeSpec(), Qt::UTC); + QCOMPARE(offset2.offsetFromUtc(), 0); + QCOMPARE(offset2.date(), offsetDate); + QCOMPARE(offset2.time(), offsetTime); + + QDateTime offset3(offsetDate, offsetTime, Qt::OffsetFromUTC, 60 * 60); + QCOMPARE(offset3.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(offset3.offsetFromUtc(), 60 * 60); + QCOMPARE(offset3.date(), offsetDate); + QCOMPARE(offset3.time(), offsetTime); + + QDateTime offset4(offsetDate, QTime(), Qt::OffsetFromUTC, 60 * 60); + QCOMPARE(offset4.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(offset4.offsetFromUtc(), 60 * 60); + QCOMPARE(offset4.date(), offsetDate); + QCOMPARE(offset4.time(), QTime(0, 0, 0)); } void tst_QDateTime::operator_eq() @@ -390,7 +422,10 @@ void tst_QDateTime::setTimeSpec() QCOMPARE(dateTime.date(), expectedDate); QCOMPARE(dateTime.time(), expectedTime); - QCOMPARE(dateTime.timeSpec(), newTimeSpec); + if (newTimeSpec == Qt::OffsetFromUTC) + QCOMPARE(dateTime.timeSpec(), Qt::UTC); + else + QCOMPARE(dateTime.timeSpec(), newTimeSpec); } void tst_QDateTime::setTime_t() @@ -398,10 +433,12 @@ void tst_QDateTime::setTime_t() QDateTime dt1; dt1.setTime_t(0); QCOMPARE(dt1.toUTC(), QDateTime(QDate(1970, 1, 1), QTime(), Qt::UTC)); + QCOMPARE(dt1.timeSpec(), Qt::LocalTime); dt1.setTimeSpec(Qt::UTC); dt1.setTime_t(0); QCOMPARE(dt1, QDateTime(QDate(1970, 1, 1), QTime(), Qt::UTC)); + QCOMPARE(dt1.timeSpec(), Qt::UTC); dt1.setTime_t(123456); QCOMPARE(dt1, QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36), Qt::UTC)); @@ -434,6 +471,12 @@ void tst_QDateTime::setTime_t() dt2.setTime_t(0x7FFFFFFF); QCOMPARE(dt2, QDateTime(QDate(2038, 1, 19), QTime(4, 14, 7), Qt::LocalTime)); } + + dt1 = QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::OffsetFromUTC, 60 * 60); + dt1.setTime_t(123456); + QCOMPARE(dt1, QDateTime(QDate(1970, 1, 2), QTime(10, 17, 36), Qt::UTC)); + QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(dt1.offsetFromUtc(), 60 * 60); } void tst_QDateTime::setMSecsSinceEpoch_data() @@ -503,6 +546,8 @@ void tst_QDateTime::setMSecsSinceEpoch() dt.setMSecsSinceEpoch(msecs); QCOMPARE(dt, utc); + QCOMPARE(dt.timeSpec(), Qt::UTC); + if (europeanTimeZone) { QCOMPARE(dt.toLocalTime(), european); @@ -512,6 +557,7 @@ void tst_QDateTime::setMSecsSinceEpoch() localDt.setMSecsSinceEpoch(msecs); QCOMPARE(localDt, utc); + QCOMPARE(localDt.timeSpec(), Qt::LocalTime); } QCOMPARE(dt.toMSecsSinceEpoch(), msecs); @@ -535,20 +581,42 @@ void tst_QDateTime::fromMSecsSinceEpoch() QFETCH(QDateTime, utc); QFETCH(QDateTime, european); - QDateTime dt(QDateTime::fromMSecsSinceEpoch(msecs)); + QDateTime dtLocal = QDateTime::fromMSecsSinceEpoch(msecs, Qt::LocalTime); + QDateTime dtUtc = QDateTime::fromMSecsSinceEpoch(msecs, Qt::UTC); + QDateTime dtOffset = QDateTime::fromMSecsSinceEpoch(msecs, Qt::OffsetFromUTC, 60*60); - QCOMPARE(dt, utc); - if (europeanTimeZone) - QCOMPARE(dt.toLocalTime(), european); + QCOMPARE(dtLocal, utc); - QCOMPARE(dt.toMSecsSinceEpoch(), msecs); + QCOMPARE(dtUtc, utc); + QCOMPARE(dtUtc.date(), utc.date()); + QCOMPARE(dtUtc.time(), utc.time()); + + QCOMPARE(dtOffset, utc); + QCOMPARE(dtOffset.utcOffset(), 60*60); + QCOMPARE(dtOffset.time(), utc.time().addMSecs(60*60*1000)); + + if (europeanTimeZone) { + QCOMPARE(dtLocal.toLocalTime(), european); + QCOMPARE(dtUtc.toLocalTime(), european); + QCOMPARE(dtOffset.toLocalTime(), european); + } else { + QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo"); + } + + QCOMPARE(dtLocal.toMSecsSinceEpoch(), msecs); + QCOMPARE(dtUtc.toMSecsSinceEpoch(), msecs); + QCOMPARE(dtOffset.toMSecsSinceEpoch(), msecs); if (quint64(msecs / 1000) < 0xFFFFFFFF) { - QCOMPARE(qint64(dt.toTime_t()), msecs / 1000); + QCOMPARE(qint64(dtLocal.toTime_t()), msecs / 1000); + QCOMPARE(qint64(dtUtc.toTime_t()), msecs / 1000); + QCOMPARE(qint64(dtOffset.toTime_t()), msecs / 1000); } QDateTime reference(QDate(1970, 1, 1), QTime(), Qt::UTC); - QCOMPARE(dt, reference.addMSecs(msecs)); + QCOMPARE(dtLocal, reference.addMSecs(msecs)); + QCOMPARE(dtUtc, reference.addMSecs(msecs)); + QCOMPARE(dtOffset, reference.addMSecs(msecs)); } void tst_QDateTime::toString_isoDate_data() @@ -563,7 +631,7 @@ void tst_QDateTime::toString_isoDate_data() << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC) << QString("1978-11-09T13:28:34.000Z"); QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34)); - dt.setUtcOffset(19800); + dt.setOffsetFromUtc(19800); QTest::newRow("positive OffsetFromUTC") << dt << QString("1978-11-09T13:28:34.000+05:30"); @@ -673,6 +741,26 @@ void tst_QDateTime::addDays() QCOMPARE(dt.time(), QTime(12, 34, 56)); } + // Test preserves TimeSpec + QDateTime dt1(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC); + QDateTime dt2 = dt1.addDays(2); + QCOMPARE(dt2.date(), QDate(2013, 1, 3)); + QCOMPARE(dt2.time(), QTime(0, 0, 0)); + QCOMPARE(dt2.timeSpec(), Qt::UTC); + + dt1 = QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::LocalTime); + dt2 = dt1.addDays(2); + QCOMPARE(dt2.date(), QDate(2013, 1, 3)); + QCOMPARE(dt2.time(), QTime(0, 0, 0)); + QCOMPARE(dt2.timeSpec(), Qt::LocalTime); + + dt1 = QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::OffsetFromUTC, 60*60); + dt2 = dt1.addDays(2); + QCOMPARE(dt2.date(), QDate(2013, 1, 3)); + QCOMPARE(dt2.time(), QTime(0, 0, 0)); + QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(dt2.offsetFromUtc(), 60 * 60); + // ### test invalid QDateTime() } @@ -680,7 +768,7 @@ void tst_QDateTime::addDays() void tst_QDateTime::addMonths_data() { QTest::addColumn<int>("months"); - QTest::addColumn<QDate>("dt"); + QTest::addColumn<QDate>("resultDate"); QTest::newRow("-15") << -15 << QDate(2002, 10, 31); QTest::newRow("-14") << -14 << QDate(2002, 11, 30); @@ -718,20 +806,37 @@ void tst_QDateTime::addMonths_data() void tst_QDateTime::addMonths() { - QFETCH(QDate, dt); QFETCH(int, months); - - QDateTime start(QDate(2004, 1, 31), QTime(12, 34, 56)); - QCOMPARE(start.addMonths(months).date(), dt); - QCOMPARE(start.addMonths(months).time(), QTime(12, 34, 56)); + QFETCH(QDate, resultDate); + + QDate testDate(2004, 1, 31); + QTime testTime(12, 34, 56); + QDateTime start(testDate, testTime); + QDateTime end = start.addMonths(months); + QCOMPARE(end.date(), resultDate); + QCOMPARE(end.time(), testTime); + QCOMPARE(end.timeSpec(), Qt::LocalTime); + + start = QDateTime(testDate, testTime, Qt::UTC); + end = start.addMonths(months); + QCOMPARE(end.date(), resultDate); + QCOMPARE(end.time(), testTime); + QCOMPARE(end.timeSpec(), Qt::UTC); + + start = QDateTime(testDate, testTime, Qt::OffsetFromUTC, 60 * 60); + end = start.addMonths(months); + QCOMPARE(end.date(), resultDate); + QCOMPARE(end.time(), testTime); + QCOMPARE(end.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(end.offsetFromUtc(), 60 * 60); } void tst_QDateTime::addYears_data() { QTest::addColumn<int>("years1"); QTest::addColumn<int>("years2"); - QTest::addColumn<QDate>("start"); - QTest::addColumn<QDate>("dt"); + QTest::addColumn<QDate>("startDate"); + QTest::addColumn<QDate>("resultDate"); QTest::newRow("0") << 0 << 0 << QDate(1752, 9, 14) << QDate(1752, 9, 14); QTest::newRow("4000 - 4000") << 4000 << -4000 << QDate(1752, 9, 14) << QDate(1752, 9, 14); @@ -754,12 +859,28 @@ void tst_QDateTime::addYears() { QFETCH(int, years1); QFETCH(int, years2); - QFETCH(QDate, start); - QFETCH(QDate, dt); - - QDateTime startdt(start, QTime(14, 25, 36)); - QCOMPARE(startdt.addYears(years1).addYears(years2).date(), dt); - QCOMPARE(startdt.addYears(years1).addYears(years2).time(), QTime(14, 25, 36)); + QFETCH(QDate, startDate); + QFETCH(QDate, resultDate); + + QTime testTime(14, 25, 36); + QDateTime start(startDate, testTime); + QDateTime end = start.addYears(years1).addYears(years2); + QCOMPARE(end.date(), resultDate); + QCOMPARE(end.time(), testTime); + QCOMPARE(end.timeSpec(), Qt::LocalTime); + + start = QDateTime(startDate, testTime, Qt::UTC); + end = start.addYears(years1).addYears(years2); + QCOMPARE(end.date(), resultDate); + QCOMPARE(end.time(), testTime); + QCOMPARE(end.timeSpec(), Qt::UTC); + + start = QDateTime(startDate, testTime, Qt::OffsetFromUTC, 60 * 60); + end = start.addYears(years1).addYears(years2); + QCOMPARE(end.date(), resultDate); + QCOMPARE(end.time(), testTime); + QCOMPARE(end.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(end.offsetFromUtc(), 60 * 60); } void tst_QDateTime::addSecs_data() @@ -831,6 +952,13 @@ void tst_QDateTime::addSecs_data() << QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), Qt::UTC); QTest::newRow("invalid") << invalidDateTime() << 1 << invalidDateTime(); + + // Check Offset details are preserved + QTest::newRow("offset0") << QDateTime(QDate(2013, 1, 1), QTime(1, 2, 3), + Qt::OffsetFromUTC, 60 * 60) + << 60 * 60 + << QDateTime(QDate(2013, 1, 1), QTime(2, 2, 3), + Qt::OffsetFromUTC, 60 * 60); } void tst_QDateTime::addSecs() @@ -842,7 +970,11 @@ void tst_QDateTime::addSecs() #ifdef Q_OS_IRIX QEXPECT_FAIL("cet4", "IRIX databases say 1970 had DST", Abort); #endif - QCOMPARE(dt.addSecs(nsecs), result); + QDateTime test = dt.addSecs(nsecs); + QCOMPARE(test, result); + QCOMPARE(test.timeSpec(), dt.timeSpec()); + if (test.timeSpec() == Qt::OffsetFromUTC) + QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc()); QCOMPARE(result.addSecs(-nsecs), dt); } @@ -860,14 +992,18 @@ void tst_QDateTime::addMSecs() #ifdef Q_OS_IRIX QEXPECT_FAIL("cet4", "IRIX databases say 1970 had DST", Abort); #endif - QCOMPARE(dt.addMSecs(qint64(nsecs) * 1000), result); + QDateTime test = dt.addMSecs(qint64(nsecs) * 1000); + QCOMPARE(test, result); + QCOMPARE(test.timeSpec(), dt.timeSpec()); + if (test.timeSpec() == Qt::OffsetFromUTC) + QCOMPARE(test.offsetFromUtc(), dt.offsetFromUtc()); QCOMPARE(result.addMSecs(qint64(-nsecs) * 1000), dt); } void tst_QDateTime::toTimeSpec_data() { - QTest::addColumn<QDateTime>("utc"); - QTest::addColumn<QDateTime>("local"); + QTest::addColumn<QDateTime>("fromUtc"); + QTest::addColumn<QDateTime>("fromLocal"); QTime utcTime(4, 20, 30); QTime localStandardTime(5, 20, 30); @@ -946,18 +1082,59 @@ void tst_QDateTime::toTimeSpec_data() void tst_QDateTime::toTimeSpec() { if (europeanTimeZone) { - QFETCH(QDateTime, utc); - QFETCH(QDateTime, local); + QFETCH(QDateTime, fromUtc); + QFETCH(QDateTime, fromLocal); + + QDateTime utcToUtc = fromUtc.toTimeSpec(Qt::UTC); + QDateTime localToLocal = fromLocal.toTimeSpec(Qt::LocalTime); + QDateTime utcToLocal = fromUtc.toTimeSpec(Qt::LocalTime); + QDateTime localToUtc = fromLocal.toTimeSpec(Qt::UTC); + QDateTime utcToOffset = fromUtc.toTimeSpec(Qt::OffsetFromUTC); + QDateTime localToOffset = fromLocal.toTimeSpec(Qt::OffsetFromUTC); + + QCOMPARE(utcToUtc, fromUtc); + QCOMPARE(utcToUtc.date(), fromUtc.date()); + QCOMPARE(utcToUtc.time(), fromUtc.time()); + QCOMPARE(utcToUtc.timeSpec(), Qt::UTC); + + QCOMPARE(localToLocal, fromLocal); + QCOMPARE(localToLocal.date(), fromLocal.date()); + QCOMPARE(localToLocal.time(), fromLocal.time()); + QCOMPARE(localToLocal.timeSpec(), Qt::LocalTime); - QCOMPARE(utc.toTimeSpec(Qt::UTC), utc); - QCOMPARE(local.toTimeSpec(Qt::LocalTime), local); #ifdef Q_OS_IRIX QEXPECT_FAIL("summer2", "IRIX databases say 1970 had DST", Abort); #endif - QCOMPARE(utc.toTimeSpec(Qt::LocalTime), local); - QCOMPARE(local.toTimeSpec(Qt::UTC), utc); - QCOMPARE(utc.toTimeSpec(Qt::UTC), local.toTimeSpec(Qt::UTC)); - QCOMPARE(utc.toTimeSpec(Qt::LocalTime), local.toTimeSpec(Qt::LocalTime)); + QCOMPARE(utcToLocal, fromLocal); + QCOMPARE(utcToLocal.date(), fromLocal.date()); + QCOMPARE(utcToLocal.time(), fromLocal.time()); + QCOMPARE(utcToLocal.timeSpec(), Qt::LocalTime); + + QCOMPARE(localToUtc, fromUtc); + QCOMPARE(localToUtc.date(), fromUtc.date()); + QCOMPARE(localToUtc.time(), fromUtc.time()); + QCOMPARE(localToUtc.timeSpec(), Qt::UTC); + + QCOMPARE(utcToUtc, localToUtc); + QCOMPARE(utcToUtc.date(), localToUtc.date()); + QCOMPARE(utcToUtc.time(), localToUtc.time()); + QCOMPARE(utcToUtc.timeSpec(), Qt::UTC); + + QCOMPARE(utcToLocal, localToLocal); + QCOMPARE(utcToLocal.date(), localToLocal.date()); + QCOMPARE(utcToLocal.time(), localToLocal.time()); + QCOMPARE(utcToLocal.timeSpec(), Qt::LocalTime); + + // OffsetToUTC becomes UTC + QCOMPARE(utcToOffset, fromUtc); + QCOMPARE(utcToOffset.date(), fromUtc.date()); + QCOMPARE(utcToOffset.time(), fromUtc.time()); + QCOMPARE(utcToOffset.timeSpec(), Qt::UTC); + + QCOMPARE(localToOffset, fromUtc); + QCOMPARE(localToOffset.date(), fromUtc.date()); + QCOMPARE(localToOffset.time(), fromUtc.time()); + QCOMPARE(localToOffset.timeSpec(), Qt::UTC); } else { QSKIP("Not tested with timezone other than Central European (CET/CST)"); } @@ -971,15 +1148,15 @@ void tst_QDateTime::toLocalTime_data() void tst_QDateTime::toLocalTime() { if (europeanTimeZone) { - QFETCH(QDateTime, utc); - QFETCH(QDateTime, local); + QFETCH(QDateTime, fromUtc); + QFETCH(QDateTime, fromLocal); - QCOMPARE(local.toLocalTime(), local); + QCOMPARE(fromLocal.toLocalTime(), fromLocal); #ifdef Q_OS_IRIX QEXPECT_FAIL("summer2", "IRIX databases say 1970 had DST", Abort); #endif - QCOMPARE(utc.toLocalTime(), local); - QCOMPARE(utc.toLocalTime(), local.toLocalTime()); + QCOMPARE(fromUtc.toLocalTime(), fromLocal); + QCOMPARE(fromUtc.toLocalTime(), fromLocal.toLocalTime()); } else { QSKIP("Not tested with timezone other than Central European (CET/CST)"); } @@ -993,15 +1170,15 @@ void tst_QDateTime::toUTC_data() void tst_QDateTime::toUTC() { if (europeanTimeZone) { - QFETCH(QDateTime, utc); - QFETCH(QDateTime, local); + QFETCH(QDateTime, fromUtc); + QFETCH(QDateTime, fromLocal); - QCOMPARE(utc.toUTC(), utc); + QCOMPARE(fromUtc.toUTC(), fromUtc); #ifdef Q_OS_IRIX QEXPECT_FAIL("summer2", "IRIX databases say 1970 had DST", Abort); #endif - QCOMPARE(local.toUTC(), utc); - QCOMPARE(utc.toUTC(), local.toUTC()); + QCOMPARE(fromLocal.toUTC(), fromUtc); + QCOMPARE(fromUtc.toUTC(), fromLocal.toUTC()); } else { QSKIP("Not tested with timezone other than Central European (CET/CST)"); } @@ -1331,9 +1508,9 @@ void tst_QDateTime::operator_eqeq_data() QDateTime dateTime3b = dateTime3.addDays(-1); // Ensure that different times may be equal when considering timezone. QDateTime dateTime3c(dateTime3.addSecs(3600)); - dateTime3c.setUtcOffset(3600); + dateTime3c.setOffsetFromUtc(3600); QDateTime dateTime3d(dateTime3.addSecs(-3600)); - dateTime3d.setUtcOffset(-3600); + dateTime3d.setOffsetFromUtc(-3600); // Convert from UTC to local. QDateTime dateTime3e(dateTime3.date(), dateTime3.time()); @@ -1666,12 +1843,10 @@ void tst_QDateTime::fromStringDateFormat_data() << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); QTest::newRow("ISO -01:00") << QString::fromLatin1("1987-02-13T13:24:51-01:00") << Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC); - // Not sure about these two... it will currently be created as LocalTime, but it - // should probably be UTC according to the ISO 8601 spec (see 4.2.5.1). QTest::newRow("ISO +0000") << QString::fromLatin1("1970-01-01T00:12:34+0000") - << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::LocalTime); + << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); QTest::newRow("ISO +00:00") << QString::fromLatin1("1970-01-01T00:12:34+00:00") - << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::LocalTime); + << Qt::ISODate << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); // No time specified - defaults to Qt::LocalTime. QTest::newRow("ISO data3") << QString::fromLatin1("2002-10-01") << Qt::ISODate << QDateTime(QDate(2002, 10, 1), QTime(0, 0, 0, 0), Qt::LocalTime); @@ -1922,25 +2097,47 @@ void tst_QDateTime::fromStringToStringLocale() QLocale::setDefault(def); } -void tst_QDateTime::utcOffset() +void tst_QDateTime::offsetFromUtc() { /* Check default value. */ - QCOMPARE(QDateTime().utcOffset(), 0); + QCOMPARE(QDateTime().offsetFromUtc(), 0); + + // Offset constructor + QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, 60 * 60); + QCOMPARE(dt1.offsetFromUtc(), 60 * 60); + dt1 = QDateTime(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, -60 * 60); + QCOMPARE(dt1.offsetFromUtc(), -60 * 60); + + // UTC should be 0 offset + QDateTime dt2(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC); + QCOMPARE(dt2.offsetFromUtc(), 0); + + // LocalTime should vary + if (europeanTimeZone) { + // Time definitely in Standard Time so 1 hour ahead + QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::LocalTime); + QCOMPARE(dt3.offsetFromUtc(), 1 * 60 * 60); + // Time definitely in Daylight Time so 2 hours ahead + QDateTime dt4(QDate(2013, 6, 1), QTime(0, 0, 0), Qt::LocalTime); + QCOMPARE(dt4.offsetFromUtc(), 2 * 60 * 60); + } else { + QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo"); + } } -void tst_QDateTime::setUtcOffset() +void tst_QDateTime::setOffsetFromUtc() { /* Basic tests. */ { QDateTime dt(QDateTime::currentDateTime()); dt.setTimeSpec(Qt::LocalTime); - dt.setUtcOffset(0); - QCOMPARE(dt.utcOffset(), 0); + dt.setOffsetFromUtc(0); + QCOMPARE(dt.offsetFromUtc(), 0); QCOMPARE(dt.timeSpec(), Qt::UTC); - dt.setUtcOffset(-100); - QCOMPARE(dt.utcOffset(), -100); + dt.setOffsetFromUtc(-100); + QCOMPARE(dt.offsetFromUtc(), -100); QCOMPARE(dt.timeSpec(), Qt::OffsetFromUTC); } @@ -1948,32 +2145,80 @@ void tst_QDateTime::setUtcOffset() { QDateTime dt(QDateTime::currentDateTime()); QDateTime dt2(dt); + int offset2 = dt2.offsetFromUtc(); - dt.setUtcOffset(501); + dt.setOffsetFromUtc(501); - QCOMPARE(dt.utcOffset(), 501); - QCOMPARE(dt2.utcOffset(), 0); + QCOMPARE(dt.offsetFromUtc(), 501); + QCOMPARE(dt2.offsetFromUtc(), offset2); } /* Check copying. */ { QDateTime dt(QDateTime::currentDateTime()); - dt.setUtcOffset(502); - QCOMPARE(dt.utcOffset(), 502); + dt.setOffsetFromUtc(502); + QCOMPARE(dt.offsetFromUtc(), 502); QDateTime dt2(dt); - QCOMPARE(dt2.utcOffset(), 502); + QCOMPARE(dt2.offsetFromUtc(), 502); } /* Check assignment. */ { QDateTime dt(QDateTime::currentDateTime()); - dt.setUtcOffset(502); + dt.setOffsetFromUtc(502); QDateTime dt2; dt2 = dt; - QCOMPARE(dt2.utcOffset(), 502); + QCOMPARE(dt2.offsetFromUtc(), 502); + } + + // Check spec persists + QDateTime dt1(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::OffsetFromUTC, 60 * 60); + dt1.setMSecsSinceEpoch(123456789); + QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(dt1.offsetFromUtc(), 60 * 60); + dt1.setTime_t(123456789); + QCOMPARE(dt1.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(dt1.offsetFromUtc(), 60 * 60); + + // Check datastream serialises the offset seconds + QByteArray tmp; + { + QDataStream ds(&tmp, QIODevice::WriteOnly); + ds << dt1; + } + QDateTime dt2; + { + QDataStream ds(&tmp, QIODevice::ReadOnly); + ds >> dt2; } + QCOMPARE(dt2, dt1); + QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(dt2.offsetFromUtc(), 60 * 60); +} + +void tst_QDateTime::toOffsetFromUtc() +{ + QDateTime dt1(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC); + + QDateTime dt2 = dt1.toOffsetFromUtc(60 * 60); + QCOMPARE(dt2, dt1); + QCOMPARE(dt2.timeSpec(), Qt::OffsetFromUTC); + QCOMPARE(dt2.date(), QDate(2013, 1, 1)); + QCOMPARE(dt2.time(), QTime(1, 0, 0)); + + dt2 = dt1.toOffsetFromUtc(0); + QCOMPARE(dt2, dt1); + QCOMPARE(dt2.timeSpec(), Qt::UTC); + QCOMPARE(dt2.date(), QDate(2013, 1, 1)); + QCOMPARE(dt2.time(), QTime(0, 0, 0)); + + dt2 = dt1.toTimeSpec(Qt::OffsetFromUTC); + QCOMPARE(dt2, dt1); + QCOMPARE(dt2.timeSpec(), Qt::UTC); + QCOMPARE(dt2.date(), QDate(2013, 1, 1)); + QCOMPARE(dt2.time(), QTime(0, 0, 0)); } void tst_QDateTime::getDate() @@ -2050,8 +2295,8 @@ void tst_QDateTime::utcOffsetLessThan() const QDateTime dt1(QDate(2002, 10, 10), QTime(0, 0, 0)); QDateTime dt2(dt1); - dt1.setUtcOffset(-(2 * 60 * 60)); // Minus two hours. - dt2.setUtcOffset(-(3 * 60 * 60)); // Minus three hours. + dt1.setOffsetFromUtc(-(2 * 60 * 60)); // Minus two hours. + dt2.setOffsetFromUtc(-(3 * 60 * 60)); // Minus three hours. QVERIFY(dt1 != dt2); QVERIFY(!(dt1 == dt2)); diff --git a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp index 3fa78f5f13..49b32d5534 100644 --- a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp +++ b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp @@ -42,14 +42,290 @@ #include <QtTest/QtTest> #include <QLinkedList> +struct Movable +{ + Movable(char input = 'j') : i(input), state(Constructed) + { + ++liveCount; + } + Movable(const Movable &other) + : i(other.i) + , state(Constructed) + { + check(other.state, Constructed); + ++liveCount; + } + + ~Movable() + { + check(state, Constructed); + i = 0; + --liveCount; + state = Destructed; + } + + bool operator ==(const Movable &other) const + { + check(state, Constructed); + check(other.state, Constructed); + return i == other.i; + } + + Movable &operator=(const Movable &other) + { + check(state, Constructed); + check(other.state, Constructed); + i = other.i; + return *this; + } + char i; + + static int getLiveCount() { return liveCount; } +private: + static int liveCount; + + enum State { Constructed = 106, Destructed = 110 }; + State state; + + static void check(const State state1, const State state2) + { + QCOMPARE(int(state1), int(state2)); + } +}; + +int Movable::liveCount = 0; + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE); +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(Movable); + +Q_DECLARE_METATYPE(QLinkedList<int>); + + +int qHash(const Movable& movable) +{ + return qHash(movable.i); +} + +struct Complex +{ + Complex(int val = 0) + : value(val) + , checkSum(this) + { + ++liveCount; + } + + Complex(Complex const &other) + : value(other.value) + , checkSum(this) + { + ++liveCount; + } + + Complex &operator=(Complex const &other) + { + check(); other.check(); + + value = other.value; + return *this; + } + + ~Complex() + { + --liveCount; + check(); + } + + operator int() const { return value; } + + bool operator==(Complex const &other) const + { + check(); other.check(); + return value == other.value; + } + + void check() const + { + QVERIFY(this == checkSum); + } + + static int getLiveCount() { return liveCount; } +private: + static int liveCount; + + int value; + void *checkSum; +}; + +int Complex::liveCount = 0; + +Q_DECLARE_METATYPE(Complex); + +// Tests depend on the fact that: +Q_STATIC_ASSERT(!QTypeInfo<int>::isStatic); +Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex); +Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic); +Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex); +Q_STATIC_ASSERT(QTypeInfo<Complex>::isStatic); +Q_STATIC_ASSERT(QTypeInfo<Complex>::isComplex); + class tst_QLinkedList : public QObject { Q_OBJECT private slots: void eraseValidIteratorsOnSharedList() const; void insertWithIteratorsOnSharedList() const; + void lengthInt() const; + void lengthMovable() const; + void lengthComplex() const; + void lengthSignature() const; + void firstInt() const; + void firstMovable() const; + void firstComplex() const; + void lastInt() const; + void lastMovable() const; + void lastComplex() const; + void beginInt() const; + void beginMovable() const; + void beginComplex() const; + void endInt() const; + void endMovable() const; + void endComplex() const; + void containsInt() const; + void containsMovable() const; + void containsComplex() const; + void countInt() const; + void countMovable() const; + void countComplex() const; + void emptyInt() const; + void emptyMovable() const; + void emptyComplex() const; + void endsWithInt() const; + void endsWithMovable() const; + void endsWithComplex() const; + void removeAllInt() const; + void removeAllMovable() const; + void removeAllComplex() const; + void removeOneInt() const; + void removeOneMovable() const; + void removeOneComplex() const; + void startsWithInt() const; + void startsWithMovable() const; + void startsWithComplex() const; + void takeFirstInt() const; + void takeFirstMovable() const; + void takeFirstComplex() const; + void takeLastInt() const; + void takeLastMovable() const; + void takeLastComplex() const; + void toStdListInt() const; + void toStdListMovable() const; + void toStdListComplex() const; + void testOperatorsInt() const; + void testOperatorsMovable() const; + void testOperatorsComplex() const; + void testSTLIteratorsInt() const; + void testSTLIteratorsMovable() const; + void testSTLIteratorsComplex() const; + + void initializeList() const; + + void constSharedNullInt() const; + void constSharedNullMovable() const; + void constSharedNullComplex() const; + + void setSharableInt() const; +private: + template<typename T> void length() const; + template<typename T> void first() const; + template<typename T> void last() const; + template<typename T> void begin() const; + template<typename T> void end() const; + template<typename T> void contains() const; + template<typename T> void count() const; + template<typename T> void empty() const; + template<typename T> void endsWith() const; + template<typename T> void move() const; + template<typename T> void removeAll() const; + template<typename T> void removeOne() const; + template<typename T> void startsWith() const; + template<typename T> void swap() const; + template<typename T> void takeFirst() const; + template<typename T> void takeLast() const; + template<typename T> void toStdList() const; + template<typename T> void value() const; + + template<typename T> void testOperators() const; + template<typename T> void testSTLIterators() const; + + template<typename T> void constSharedNull() const; + + int dummyForGuard; }; +template<typename T> struct SimpleValue +{ + static T at(int index) + { + return values[index % maxSize]; + } + static const uint maxSize = 7; + static const T values[maxSize]; +}; + +template<> +const int SimpleValue<int>::values[] = { 10, 20, 30, 40, 100, 101, 102 }; +template<> +const Movable SimpleValue<Movable>::values[] = { 10, 20, 30, 40, 100, 101, 102 }; +template<> +const Complex SimpleValue<Complex>::values[] = { 10, 20, 30, 40, 100, 101, 102 }; + +// Make some macros for the tests to use in order to be slightly more readable... +#define T_FOO SimpleValue<T>::at(0) +#define T_BAR SimpleValue<T>::at(1) +#define T_BAZ SimpleValue<T>::at(2) +#define T_CAT SimpleValue<T>::at(3) +#define T_DOG SimpleValue<T>::at(4) +#define T_BLAH SimpleValue<T>::at(5) +#define T_WEEE SimpleValue<T>::at(6) + +template<typename T> +void tst_QLinkedList::length() const +{ + /* Empty list. */ + { + const QLinkedList<T> list; + QCOMPARE(list.size(), 0); + } + + /* One entry. */ + { + QLinkedList<T> list; + list.append(T_FOO); + QCOMPARE(list.size(), 1); + } + + /* Two entries. */ + { + QLinkedList<T> list; + list.append(T_FOO); + list.append(T_BAR); + QCOMPARE(list.size(), 2); + } + + /* Three entries. */ + { + QLinkedList<T> list; + list.append(T_FOO); + list.append(T_BAR); + list.append(T_BAZ); + QCOMPARE(list.size(), 3); + } +} + void tst_QLinkedList::eraseValidIteratorsOnSharedList() const { QLinkedList<int> a, b; @@ -92,5 +368,733 @@ void tst_QLinkedList::insertWithIteratorsOnSharedList() const QCOMPARE(*i2, 10); } -QTEST_MAIN(tst_QLinkedList) +void tst_QLinkedList::lengthInt() const +{ + length<int>(); +} + +void tst_QLinkedList::lengthMovable() const +{ + const int liveCount = Movable::getLiveCount(); + length<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::lengthComplex() const +{ + const int liveCount = Complex::getLiveCount(); + length<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +void tst_QLinkedList::lengthSignature() const +{ + /* Constness. */ + { + const QLinkedList<int> list; + /* The function should be const. */ + list.size(); + } +} + +template<typename T> +void tst_QLinkedList::first() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR; + + QCOMPARE(list.first(), T_FOO); + + // remove an item, make sure it still works + list.pop_front(); + QVERIFY(list.size() == 1); + QCOMPARE(list.first(), T_BAR); +} + +void tst_QLinkedList::firstInt() const +{ + first<int>(); +} + +void tst_QLinkedList::firstMovable() const +{ + const int liveCount = Movable::getLiveCount(); + first<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::firstComplex() const +{ + const int liveCount = Complex::getLiveCount(); + first<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::last() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR; + + QCOMPARE(list.last(), T_BAR); + + // remove an item, make sure it still works + list.pop_back(); + QVERIFY(list.size() == 1); + QCOMPARE(list.last(), T_FOO); +} + +void tst_QLinkedList::lastInt() const +{ + last<int>(); +} + +void tst_QLinkedList::lastMovable() const +{ + const int liveCount = Movable::getLiveCount(); + last<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::lastComplex() const +{ + const int liveCount = Complex::getLiveCount(); + last<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::begin() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR; + + QCOMPARE(*list.begin(), T_FOO); + + // remove an item, make sure it still works + list.pop_front(); + QVERIFY(list.size() == 1); + QCOMPARE(*list.begin(), T_BAR); +} + +void tst_QLinkedList::beginInt() const +{ + begin<int>(); +} + +void tst_QLinkedList::beginMovable() const +{ + const int liveCount = Movable::getLiveCount(); + begin<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::beginComplex() const +{ + const int liveCount = Complex::getLiveCount(); + begin<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::end() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR; + + QCOMPARE(*--list.end(), T_BAR); + + // remove an item, make sure it still works + list.pop_back(); + QVERIFY(list.size() == 1); + QCOMPARE(*--list.end(), T_FOO); +} + +void tst_QLinkedList::endInt() const +{ + end<int>(); +} + +void tst_QLinkedList::endMovable() const +{ + const int liveCount = Movable::getLiveCount(); + end<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::endComplex() const +{ + const int liveCount = Complex::getLiveCount(); + end<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::contains() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR << T_BAZ; + + QVERIFY(list.contains(T_FOO) == true); + QVERIFY(list.contains(T_BLAH) != true); + + // add it and make sure it matches + list.append(T_BLAH); + QVERIFY(list.contains(T_BLAH) == true); +} + +void tst_QLinkedList::containsInt() const +{ + contains<int>(); +} + +void tst_QLinkedList::containsMovable() const +{ + const int liveCount = Movable::getLiveCount(); + contains<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::containsComplex() const +{ + const int liveCount = Complex::getLiveCount(); + contains<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::count() const +{ + QLinkedList<T> list; + + // starts empty + QVERIFY(list.count() == 0); + + // goes up + list.append(T_FOO); + QVERIFY(list.count() == 1); + + // and up + list.append(T_BAR); + QVERIFY(list.count() == 2); + + // and down + list.pop_back(); + QVERIFY(list.count() == 1); + + // and empty. :) + list.pop_back(); + QVERIFY(list.count() == 0); +} + +void tst_QLinkedList::countInt() const +{ + count<int>(); +} + +void tst_QLinkedList::countMovable() const +{ + const int liveCount = Movable::getLiveCount(); + count<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::countComplex() const +{ + const int liveCount = Complex::getLiveCount(); + count<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::empty() const +{ + QLinkedList<T> list; + + // make sure it starts empty + QVERIFY(list.empty()); + + // and doesn't stay empty + list.append(T_FOO); + QVERIFY(!list.empty()); + + // and goes back to being empty + list.pop_back(); + QVERIFY(list.empty()); +} + +void tst_QLinkedList::emptyInt() const +{ + empty<int>(); +} + +void tst_QLinkedList::emptyMovable() const +{ + const int liveCount = Movable::getLiveCount(); + empty<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::emptyComplex() const +{ + const int liveCount = Complex::getLiveCount(); + empty<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::endsWith() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR << T_BAZ; + + // test it returns correctly in both cases + QVERIFY(list.endsWith(T_BAZ)); + QVERIFY(!list.endsWith(T_BAR)); + + // remove an item and make sure the end item changes + list.pop_back(); + QVERIFY(list.endsWith(T_BAR)); +} + +void tst_QLinkedList::endsWithInt() const +{ + endsWith<int>(); +} + +void tst_QLinkedList::endsWithMovable() const +{ + const int liveCount = Movable::getLiveCount(); + endsWith<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::endsWithComplex() const +{ + const int liveCount = Complex::getLiveCount(); + endsWith<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::removeAll() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR << T_BAZ; + + // remove one instance + list.removeAll(T_BAR); + QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ); + + // many instances + list << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ << T_FOO << T_BAR << T_BAZ; + list.removeAll(T_BAR); + QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ); + + // try remove something that doesn't exist + list.removeAll(T_WEEE); + QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ << T_FOO << T_BAZ); +} + +void tst_QLinkedList::removeAllInt() const +{ + removeAll<int>(); +} + +void tst_QLinkedList::removeAllMovable() const +{ + const int liveCount = Movable::getLiveCount(); + removeAll<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::removeAllComplex() const +{ + const int liveCount = Complex::getLiveCount(); + removeAll<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::removeOne() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR << T_BAZ; + + // middle + list.removeOne(T_BAR); + QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAZ); + + // start + list.removeOne(T_FOO); + QCOMPARE(list, QLinkedList<T>() << T_BAZ); + + // last + list.removeOne(T_BAZ); + QCOMPARE(list, QLinkedList<T>()); + + // make sure it really only removes one :) + list << T_FOO << T_FOO; + list.removeOne(T_FOO); + QCOMPARE(list, QLinkedList<T>() << T_FOO); + + // try remove something that doesn't exist + list.removeOne(T_WEEE); + QCOMPARE(list, QLinkedList<T>() << T_FOO); +} + +void tst_QLinkedList::removeOneInt() const +{ + removeOne<int>(); +} + +void tst_QLinkedList::removeOneMovable() const +{ + const int liveCount = Movable::getLiveCount(); + removeOne<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::removeOneComplex() const +{ + const int liveCount = Complex::getLiveCount(); + removeOne<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::startsWith() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR << T_BAZ; + + // make sure it starts ok + QVERIFY(list.startsWith(T_FOO)); + + // remove an item + list.removeFirst(); + QVERIFY(list.startsWith(T_BAR)); +} + +void tst_QLinkedList::startsWithInt() const +{ + startsWith<int>(); +} + +void tst_QLinkedList::startsWithMovable() const +{ + const int liveCount = Movable::getLiveCount(); + startsWith<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::startsWithComplex() const +{ + const int liveCount = Complex::getLiveCount(); + startsWith<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::takeFirst() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR << T_BAZ; + + QCOMPARE(list.takeFirst(), T_FOO); + QVERIFY(list.size() == 2); + QCOMPARE(list.takeFirst(), T_BAR); + QVERIFY(list.size() == 1); + QCOMPARE(list.takeFirst(), T_BAZ); + QVERIFY(list.size() == 0); +} + +void tst_QLinkedList::takeFirstInt() const +{ + takeFirst<int>(); +} + +void tst_QLinkedList::takeFirstMovable() const +{ + const int liveCount = Movable::getLiveCount(); + takeFirst<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::takeFirstComplex() const +{ + const int liveCount = Complex::getLiveCount(); + takeFirst<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::takeLast() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR << T_BAZ; + + QCOMPARE(list.takeLast(), T_BAZ); + QCOMPARE(list.takeLast(), T_BAR); + QCOMPARE(list.takeLast(), T_FOO); +} + +void tst_QLinkedList::takeLastInt() const +{ + takeLast<int>(); +} + +void tst_QLinkedList::takeLastMovable() const +{ + const int liveCount = Movable::getLiveCount(); + takeLast<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::takeLastComplex() const +{ + const int liveCount = Complex::getLiveCount(); + takeLast<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::toStdList() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR << T_BAZ; + + // yuck. + std::list<T> slist; + slist.push_back(T_FOO); + slist.push_back(T_BAR); + slist.push_back(T_BAZ); + + QCOMPARE(list.toStdList(), slist); + QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ); +} + +void tst_QLinkedList::toStdListInt() const +{ + toStdList<int>(); +} + +void tst_QLinkedList::toStdListMovable() const +{ + const int liveCount = Movable::getLiveCount(); + toStdList<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::toStdListComplex() const +{ + const int liveCount = Complex::getLiveCount(); + toStdList<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::testOperators() const +{ + QLinkedList<T> list; + list << T_FOO << T_BAR << T_BAZ; + + QLinkedList<T> listtwo; + listtwo << T_FOO << T_BAR << T_BAZ; + + // test equal + QVERIFY(list == listtwo); + + // not equal + listtwo.append(T_CAT); + QVERIFY(list != listtwo); + + // += + list += listtwo; + QVERIFY(list.size() == 7); + QVERIFY(listtwo.size() == 4); + QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ + << T_FOO << T_BAR << T_BAZ << T_CAT); + + // = + list = listtwo; + QCOMPARE(list, listtwo); + QCOMPARE(list, QLinkedList<T>() << T_FOO << T_BAR << T_BAZ << T_CAT); +} + +void tst_QLinkedList::testOperatorsInt() const +{ + testOperators<int>(); +} + +void tst_QLinkedList::testOperatorsMovable() const +{ + const int liveCount = Movable::getLiveCount(); + testOperators<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::testOperatorsComplex() const +{ + const int liveCount = Complex::getLiveCount(); + testOperators<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +template<typename T> +void tst_QLinkedList::testSTLIterators() const +{ + QLinkedList<T> list; + + // create a list + list << T_FOO << T_BAR << T_BAZ; + typename QLinkedList<T>::iterator it = list.begin(); + QCOMPARE(*it, T_FOO); it++; + QCOMPARE(*it, T_BAR); it++; + QCOMPARE(*it, T_BAZ); it++; + QCOMPARE(it, list.end()); it--; + + // walk backwards + QCOMPARE(*it, T_BAZ); it--; + QCOMPARE(*it, T_BAR); it--; + QCOMPARE(*it, T_FOO); + + // test erase + it = list.erase(it); + QVERIFY(list.size() == 2); + QCOMPARE(*it, T_BAR); + + // test multiple erase + it = list.erase(it, it + 2); + QVERIFY(list.size() == 0); + QCOMPARE(it, list.end()); + + // insert again + it = list.insert(it, T_FOO); + QVERIFY(list.size() == 1); + QCOMPARE(*it, T_FOO); + + // insert again + it = list.insert(it, T_BAR); + QVERIFY(list.size() == 2); + QCOMPARE(*it++, T_BAR); + QCOMPARE(*it, T_FOO); +} + +void tst_QLinkedList::testSTLIteratorsInt() const +{ + testSTLIterators<int>(); +} + +void tst_QLinkedList::testSTLIteratorsMovable() const +{ + const int liveCount = Movable::getLiveCount(); + testSTLIterators<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::testSTLIteratorsComplex() const +{ + const int liveCount = Complex::getLiveCount(); + testSTLIterators<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + +void tst_QLinkedList::initializeList() const +{ +#ifdef Q_COMPILER_INITIALIZER_LISTS + QLinkedList<int> v1 { 2, 3, 4 }; + QCOMPARE(v1, QLinkedList<int>() << 2 << 3 << 4); + QCOMPARE(v1, (QLinkedList<int> { 2, 3, 4})); + + QLinkedList<QLinkedList<int>> v2{ v1, { 1 }, QLinkedList<int>(), { 2, 3, 4 } }; + QLinkedList<QLinkedList<int>> v3; + v3 << v1 << (QLinkedList<int>() << 1) << QLinkedList<int>() << v1; + QCOMPARE(v3, v2); +#endif +} + + +template<typename T> +void tst_QLinkedList::constSharedNull() const +{ + QLinkedList<T> list1; + list1.setSharable(false); + QVERIFY(list1.isDetached()); + + QLinkedList<T> list2; + list2.setSharable(true); + QVERIFY(!list2.isDetached()); +} + +void tst_QLinkedList::constSharedNullInt() const +{ + constSharedNull<int>(); +} + +void tst_QLinkedList::constSharedNullMovable() const +{ + const int liveCount = Movable::getLiveCount(); + constSharedNull<Movable>(); + QCOMPARE(liveCount, Movable::getLiveCount()); +} + +void tst_QLinkedList::constSharedNullComplex() const +{ + const int liveCount = Complex::getLiveCount(); + constSharedNull<Complex>(); + QCOMPARE(liveCount, Complex::getLiveCount()); +} + + +void tst_QLinkedList::setSharableInt() const +{ + QLinkedList<int> orglist; + orglist << 0 << 1 << 2 << 3 << 4 << 5; + int size = 6; + + QLinkedList<int> list; + list = orglist; + + QVERIFY(!list.isDetached()); + list.setSharable(true); + + QCOMPARE(list.size(), size); + + { + QLinkedList<int> copy(list); + QVERIFY(!copy.isDetached()); + QVERIFY(copy.isSharedWith(list)); + } + + list.setSharable(false); + QVERIFY(list.isDetached() || list.isSharedWith(QLinkedList<int>())); + + { + QLinkedList<int> copy(list); + + QVERIFY(copy.isDetached() || copy.isSharedWith(QLinkedList<int>())); + QCOMPARE(copy.size(), size); + QCOMPARE(copy, list); + } + + list.setSharable(true); + + { + QLinkedList<int> copy(list); + + QVERIFY(!copy.isDetached()); + QVERIFY(copy.isSharedWith(list)); + } + + QLinkedList<int>::const_iterator it = list.constBegin(); + for (int i = 0; i < list.size(); ++i) { + QCOMPARE(int(*it), i); + ++it; + } + + QCOMPARE(list.size(), size); +} + +QTEST_APPLESS_MAIN(tst_QLinkedList) #include "tst_qlinkedlist.moc" diff --git a/tests/auto/gui/gui.pro b/tests/auto/gui/gui.pro index 87aea70acb..b6c55c5eaa 100644 --- a/tests/auto/gui/gui.pro +++ b/tests/auto/gui/gui.pro @@ -8,3 +8,5 @@ SUBDIRS=\ text \ util \ itemmodels \ + +!contains(QT_CONFIG, opengl(es1|es2)?): SUBDIRS -= qopengl diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index 0d0a300eac..e4d9ce9d27 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -24,3 +24,6 @@ SUBDIRS=\ !qtHaveModule(widgets): SUBDIRS -= \ qmouseevent_modal \ qtouchevent + +!qtHaveModule(network): SUBDIRS -= \ + qguieventloop diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index dcda9f7fd7..8d31fcdf13 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -259,6 +259,7 @@ private slots: void taskQTBUG_25333_adjustViewOptionsForIndex(); void taskQTBUG_18539_emitLayoutChanged(); void taskQTBUG_8176_emitOnExpandAll(); + void testInitialFocus(); }; class QtTestModel: public QAbstractItemModel @@ -4239,6 +4240,20 @@ void tst_QTreeView::taskQTBUG_8176_emitOnExpandAll() QCOMPARE(spy2.size(), 1); // item2 is collapsed } +void tst_QTreeView::testInitialFocus() +{ + QTreeWidget treeWidget; + treeWidget.setColumnCount(5); + new QTreeWidgetItem(&treeWidget, QStringList(QString("1;2;3;4;5").split(";"))); + treeWidget.setTreePosition(2); + treeWidget.header()->hideSection(0); // make sure we skip hidden section(s) + treeWidget.header()->swapSections(1, 2); // make sure that we look for first visual index (and not first logical) + treeWidget.show(); + QTest::qWaitForWindowExposed(&treeWidget); + QApplication::processEvents(); + QCOMPARE(treeWidget.currentIndex().column(), 2); +} + #ifndef QT_NO_ANIMATION void tst_QTreeView::quickExpandCollapse() { diff --git a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp index 84d796f657..7bbbff5736 100644 --- a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp +++ b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp @@ -74,6 +74,9 @@ private slots: void setGeometry(); void setStyleShouldChangeSpacing(); + void testLayoutEngine_data(); + void testLayoutEngine(); + void taskQTBUG_7103_minMaxWidthNotRespected(); void taskQTBUG_27420_takeAtShouldUnparentLayout(); }; @@ -325,5 +328,157 @@ void tst_QBoxLayout::taskQTBUG_27420_takeAtShouldUnparentLayout() QVERIFY(!inner.isNull()); } + +struct Descr +{ + Descr(int min, int sh, int max = -1, bool exp= false, int _stretch = 0, bool _empty = false) + :minimumSize(min), sizeHint(sh), maximumSize(max < 0 ? QLAYOUTSIZE_MAX : max), + expanding(exp), stretch(_stretch), empty(_empty) + {} + + int minimumSize; + int sizeHint; + int maximumSize; + bool expanding; + + int stretch; + + bool empty; +}; + + +typedef QList<Descr> DescrList; +Q_DECLARE_METATYPE(DescrList); + +typedef QList<int> SizeList; +typedef QList<int> PosList; + + + +class LayoutItem : public QLayoutItem +{ +public: + LayoutItem(const Descr &descr) :m_descr(descr) {} + + QSize sizeHint() const { return QSize(m_descr.sizeHint, 100); } + QSize minimumSize() const { return QSize(m_descr.minimumSize, 0); } + QSize maximumSize() const { return QSize(m_descr.maximumSize, QLAYOUTSIZE_MAX); } + Qt::Orientations expandingDirections() const + { return m_descr.expanding ? Qt::Horizontal : Qt::Orientations(0); } + void setGeometry(const QRect &r) { m_pos = r.x(); m_size = r.width();} + QRect geometry() const { return QRect(m_pos, 0, m_size, 100); } + bool isEmpty() const { return m_descr.empty; } + +private: + Descr m_descr; + int m_pos; + int m_size; +}; + +void tst_QBoxLayout::testLayoutEngine_data() +{ + // (int min, int sh, int max = -1, bool exp= false, int _stretch = 0, bool _empty = false) + QTest::addColumn<DescrList>("itemDescriptions"); + QTest::addColumn<int>("size"); + QTest::addColumn<int>("spacing"); + QTest::addColumn<PosList>("expectedPositions"); + QTest::addColumn<SizeList>("expectedSizes"); + + QTest::newRow("Just one") + << (DescrList() << Descr(0, 100)) + << 200 + << 0 + << (PosList() << 0) + << (SizeList() << 200); + + QTest::newRow("Two non-exp") + << (DescrList() << Descr(0, 100) << Descr(0,100)) + << 400 + << 0 + << (PosList() << 0 << 200) + << (SizeList() << 200 << 200); + + QTest::newRow("Exp + non-exp") + << (DescrList() << Descr(0, 100, -1, true) << Descr(0,100)) + << 400 + << 0 + << (PosList() << 0 << 300) + << (SizeList() << 300 << 100); + + + QTest::newRow("Stretch") + << (DescrList() << Descr(0, 100, -1, false, 1) << Descr(0,100, -1, false, 2)) + << 300 + << 0 + << (PosList() << 0 << 100) + << (SizeList() << 100 << 200); + + + QTest::newRow("Spacing") + << (DescrList() << Descr(0, 100) << Descr(0,100)) + << 400 + << 10 + << (PosList() << 0 << 205) + << (SizeList() << 195 << 195); + + + QTest::newRow("Less than minimum") + << (DescrList() << Descr(100, 100, 100, false) << Descr(50, 100, 100, false)) + << 100 + << 0 + << (PosList() << 0 << 50) + << (SizeList() << 50 << 50); + + + QTest::newRow("Less than sizehint") + << (DescrList() << Descr(100, 200, 100, false) << Descr(50, 200, 100, false)) + << 200 + << 0 + << (PosList() << 0 << 100) + << (SizeList() << 100 << 100); + + QTest::newRow("Too much space") + << (DescrList() << Descr(0, 100, 100, false) << Descr(0, 100, 100, false)) + << 500 + << 0 + << (PosList() << 100 << 300) + << (SizeList() << 100 << 100); + + QTest::newRow("Empty") + << (DescrList() << Descr(0, 100, 100) << Descr(0,0,-1, false, 0, true) << Descr(0, 100, 100) ) + << 500 + << 0 + << (PosList() << 100 << 300 << 300) + << (SizeList() << 100 << 0 << 100); + +} + +void tst_QBoxLayout::testLayoutEngine() +{ + QFETCH(DescrList, itemDescriptions); + QFETCH(int, size); + QFETCH(int, spacing); + QFETCH(PosList, expectedPositions); + QFETCH(SizeList, expectedSizes); + + QHBoxLayout box; + box.setSpacing(spacing); + int i; + for (i = 0; i < itemDescriptions.count(); ++i) { + Descr descr = itemDescriptions.at(i); + LayoutItem *li = new LayoutItem(descr); + box.addItem(li); + box.setStretch(i, descr.stretch); + } + box.setGeometry(QRect(0,0,size,100)); + for (i = 0; i < expectedSizes.count(); ++i) { + int xSize = expectedSizes.at(i); + int xPos = expectedPositions.at(i); + QLayoutItem *item = box.itemAt(i); + QCOMPARE(item->geometry().width(), xSize); + QCOMPARE(item->geometry().x(), xPos); + } +} + QTEST_MAIN(tst_QBoxLayout) #include "tst_qboxlayout.moc" diff --git a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp index ffb4526f11..93262722b9 100644 --- a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp +++ b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp @@ -490,6 +490,12 @@ void tst_QAbstractButton::toggled() QTest::mouseRelease( testWidget, Qt::LeftButton ); QVERIFY( click_count == 1 ); + + testWidget->setCheckable(true); + testWidget->toggle(); + testWidget->toggle(); + QCOMPARE(int(toggle_count), 2); + testWidget->setCheckable(false); } void tst_QAbstractButton::setShortcut() diff --git a/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp index c37060f5d5..f027eda6a2 100644 --- a/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp +++ b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp @@ -359,6 +359,26 @@ void tst_QButtonGroup::testSignals() QCOMPARE(releasedSpy.count(), 1); QCOMPARE(releasedIdSpy.count(), 1); QVERIFY(releasedIdSpy.takeFirst().at(0).toInt() == 23); + + + QSignalSpy toggledSpy(&buttons, SIGNAL(buttonToggled(QAbstractButton*, bool))); + QSignalSpy toggledIdSpy(&buttons, SIGNAL(buttonToggled(int, bool))); + + pb1.setCheckable(true); + pb2.setCheckable(true); + pb1.toggle(); + QCOMPARE(toggledSpy.count(), 1); + QCOMPARE(toggledIdSpy.count(), 1); + + pb2.toggle(); + QCOMPARE(toggledSpy.count(), 3); // equals 3 since pb1 and pb2 are both toggled + QCOMPARE(toggledIdSpy.count(), 3); + + pb1.setCheckable(false); + pb2.setCheckable(false); + pb1.toggle(); + QCOMPARE(toggledSpy.count(), 3); + QCOMPARE(toggledIdSpy.count(), 3); } void tst_QButtonGroup::task106609() diff --git a/tests/manual/dialogs/filedialogpanel.cpp b/tests/manual/dialogs/filedialogpanel.cpp index 000d755cef..e234835cdb 100644 --- a/tests/manual/dialogs/filedialogpanel.cpp +++ b/tests/manual/dialogs/filedialogpanel.cpp @@ -162,6 +162,7 @@ FileDialogPanel::FileDialogPanel(QWidget *parent) , m_defaultSuffix(new QLineEdit(this)) , m_directory(new QLineEdit(this)) , m_selectedFileName(new QLineEdit(this)) + , m_useMimeTypeFilters(new QCheckBox(this)) , m_nameFilters(new QPlainTextEdit) , m_selectedNameFilter(new QLineEdit(this)) , m_deleteNonModalDialogButton(0) @@ -183,10 +184,11 @@ FileDialogPanel::FileDialogPanel(QWidget *parent) // Files QGroupBox *filesGroupBox = new QGroupBox(tr("Files / Filters")); - QFormLayout *filesLayout = new QFormLayout(filesGroupBox); + filesLayout = new QFormLayout(filesGroupBox); filesLayout->addRow(tr("Default Suffix:"), m_defaultSuffix); filesLayout->addRow(tr("Directory:"), m_directory); filesLayout->addRow(tr("Selected file:"), m_selectedFileName); + filesLayout->addRow(tr("Use mime type filters:"), m_useMimeTypeFilters); m_nameFilters->setMaximumHeight(80); filesLayout->addRow(tr("Name filters:"), m_nameFilters); filesLayout->addRow(tr("Selected name filter:"), m_selectedNameFilter); @@ -236,6 +238,8 @@ FileDialogPanel::FileDialogPanel(QWidget *parent) gridLayout->addWidget(labelsGroupBox, 1, 0); gridLayout->addWidget(buttonsGroupBox, 1, 1); + connect(m_useMimeTypeFilters, SIGNAL(toggled(bool)), this, SLOT(useMimeTypeFilters(bool))); + enableDeleteModalDialogButton(); enableDeleteNonModalDialogButton(); restoreDefaults(); @@ -461,7 +465,8 @@ void FileDialogPanel::restoreDefaults() m_customDirIcons->setChecked(d.testOption(QFileDialog::DontUseCustomDirectoryIcons)); m_directory->setText(QDir::homePath()); m_defaultSuffix->setText(QLatin1String("txt")); - m_nameFilters->setPlainText(QLatin1String("Any files (*)\nImage files (*.png *.xpm *.jpg)\nText files (*.txt)")); + m_useMimeTypeFilters->setChecked(false); + useMimeTypeFilters(false); m_selectedFileName->setText(QString()); m_selectedNameFilter->setText(QString()); foreach (LabelLineEdit *l, m_labelLineEdits) @@ -481,14 +486,36 @@ void FileDialogPanel::applySettings(QFileDialog *d) const const QString file = m_selectedFileName->text().trimmed(); if (!file.isEmpty()) d->selectFile(file); - d->setNameFilters(m_nameFilters->toPlainText().trimmed().split(QLatin1Char('\n'), QString::SkipEmptyParts)); const QString filter = m_selectedNameFilter->text().trimmed(); - if (!filter.isEmpty()) - d->selectNameFilter(filter); + const QStringList filters = m_nameFilters->toPlainText().trimmed().split(QLatin1Char('\n'), QString::SkipEmptyParts); + if (!m_useMimeTypeFilters->isChecked()) { + d->setNameFilters(filters); + if (!filter.isEmpty()) + d->selectNameFilter(filter); + } else { + d->setMimeTypeFilters(filters); + if (!filter.isEmpty()) + d->selectMimeTypeFilter(filter); + } foreach (LabelLineEdit *l, m_labelLineEdits) l->apply(d); } +void FileDialogPanel::useMimeTypeFilters(bool b) +{ + QWidget *textEdit = filesLayout->labelForField(m_nameFilters); + if (QLabel *label = qobject_cast<QLabel *>(textEdit)) + label->setText(b ? tr("Mime type filters:") : tr("Name filters:")); + QWidget *w = filesLayout->labelForField(m_selectedNameFilter); + if (QLabel *label = qobject_cast<QLabel *>(w)) + label->setText(b ? tr("Selected mime type filter:") : tr("Selected name filter:")); + + if (b) + m_nameFilters->setPlainText(QLatin1String("image/jpeg\nimage/png\ntext/plain\napplication/octet-stream")); + else + m_nameFilters->setPlainText(QLatin1String("Any files (*)\nImage files (*.png *.xpm *.jpg)\nText files (*.txt)")); +} + void FileDialogPanel::accepted() { const QFileDialog *d = qobject_cast<const QFileDialog *>(sender()); diff --git a/tests/manual/dialogs/filedialogpanel.h b/tests/manual/dialogs/filedialogpanel.h index 2e1d5d4de9..1e86e0f18e 100644 --- a/tests/manual/dialogs/filedialogpanel.h +++ b/tests/manual/dialogs/filedialogpanel.h @@ -52,6 +52,7 @@ class QCheckBox; class QComboBox; class QLineEdit; class QPlainTextEdit; +class QFormLayout; QT_END_NAMESPACE class LabelLineEdit; @@ -82,6 +83,7 @@ public slots: private slots: void enableDeleteNonModalDialogButton(); void enableDeleteModalDialogButton(); + void useMimeTypeFilters(bool); private: QString filterString() const; @@ -89,6 +91,7 @@ private: QStringList allowedSchemes() const; void applySettings(QFileDialog *d) const; + QFormLayout *filesLayout; QCheckBox *m_readOnly; QCheckBox *m_confirmOverWrite; QCheckBox *m_nameFilterDetailsVisible; @@ -103,6 +106,7 @@ private: QLineEdit *m_directory; QLineEdit *m_selectedFileName; QList<LabelLineEdit *> m_labelLineEdits; + QCheckBox *m_useMimeTypeFilters; QPlainTextEdit *m_nameFilters; QLineEdit *m_selectedNameFilter; QPushButton *m_deleteNonModalDialogButton; diff --git a/tests/manual/widgets/itemviews/qtreewidget/main.cpp b/tests/manual/widgets/itemviews/qtreewidget/main.cpp index 9428113250..0dec329cd8 100644 --- a/tests/manual/widgets/itemviews/qtreewidget/main.cpp +++ b/tests/manual/widgets/itemviews/qtreewidget/main.cpp @@ -115,13 +115,14 @@ public: // Developer no. could also have been social security number og some other id. itemInfo.append("Title"); treeWidget->setHeaderLabels(itemInfo); - radioFirstName->setChecked(true); + radioLastName->setChecked(true); connect(radioFirstName, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool))); connect(radioLastName, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool))); connect(radioDeveloperNo, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool))); connect(radioTitle, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool))); treeWidget->setTreePosition(-1); + treeWidget->header()->swapSections(0, 1); } protected slots: |